跳至主要内容

索引访问类型

Flow 的索引访问类型允许您从 对象数组元组 类型中获取属性的类型。

用法

访问对象类型的属性

1type Cat = {2  name: string,3  age: number,4  hungry: boolean,5};6
7type Hungry = Cat['hungry']; // type Hungry = boolean8const isHungry: Hungry = true; // OK - `Hungry` is an alias for `boolean`9
10// The index can be a type, not just a literal:11type AgeProp = 'age';12type Age = Cat[AgeProp]; // type Age = number13const catAge: Age = 6; // OK - `Age` is an alias for `number`

访问数组类型的元素,通过获取数组索引(即 number)处的类型

1type CatNames = Array<string>;2
3type CatName = CatNames[number]; // type CatName = string4const myCatsName: CatName = 'whiskers'; // OK - `CatName` is an alias for `string`

访问元组类型的元素

1type Pair = [string, number];2
3const name: Pair[0] = 'whiskers'; // OK - `Pair[0]` is an alias for `string`4const age: Pair[1] = 6; // OK - `Pair[1]` is an alias for `number`5const wrong: Pair[2] = true; // Error - `Pair` only has two elements
5:19-5:19: Cannot access number literal `2` on `Pair` because `Pair` [1] only has 2 elements, so index 2 is out of bounds. [invalid-tuple-index]

索引可以是联合类型,包括调用 $Keys<...> 的结果

1type Cat = {2  name: string,3  age: number,4  hungry: boolean,5};6
7type Values = Cat[$Keys<Cat>]; // type Values = string | number | boolean

索引也可以是泛型

1function getProp<O: {+[string]: mixed}, K: $Keys<O>>(o: O, k: K): O[K] {2  return o[k];3}4
5const x: number = getProp({a: 42}, 'a'); // OK6const y: string = getProp({a: 42}, 'a'); // Error - `number` is not a `string`
7getProp({a: 42}, 'b'); // Error - `b` does not exist in object type
6:19-6:39: Cannot assign `getProp(...)` to `y` because number [1] is incompatible with string [2]. [incompatible-type]
7:18-7:20: Cannot call `getProp` because property `b` is missing in object literal [1]. [prop-missing]
7:18-7:20: Cannot call `getProp` because property `b` is missing in object literal [1] in type argument `K`. [prop-missing]

您可以嵌套这些访问

1type Cat = {2  name: string,3  age: number,4  hungry: boolean,5  personality: {6    friendly: boolean,7    hungerLevel: number,8  }9};10
11type Friendly = Cat['personality']['friendly']; // type Friendly = boolean12const isFriendly: Friendly = true; // Pet the cat

可选索引访问类型

可选索引访问类型的工作方式类似于可选链。它们允许您从可空对象类型访问属性。如果您之前这样做

type T = $ElementType<$NonMaybeType<Obj>, 'prop'> | void;

您现在可以这样做

type T = Obj?.['prop'];

与可选链类似,可选索引访问类型的结果类型包括 void。如果您有一长串嵌套的可选访问,您可以将整个内容包装在 $NonMaybeType<...> 中,如果您不希望结果类型中包含 void

示例

1type TasksContent = ?{2  tasks?: Array<{3    items?: {4      metadata?: {5        title: string,6        completed: boolean,7      },8    },9  }>,10};11
12type TaskData = TasksContent?.['tasks']?.[number]?.['items']?.['metadata'];

可选链和可选索引访问类型之间存在一个细微的差别。如果您访问的对象类型不可空,则可选链的结果类型将不包含 void。对于可选索引访问类型,出于实现原因,结果类型将始终包含 void。但是,如果您的对象类型不可空,则不需要使用可选索引访问类型,而应该只使用常规的索引访问类型。

采用

要使用索引访问类型,您需要升级您的基础设施,使其支持语法

  • flowflow-parser:0.155
  • prettier: 2.3.2
  • babel: 7.14

索引访问类型是 $PropertyType$ElementType 实用类型的替代品。如果您已经熟悉这些实用类型,这里有一个快速转换指南

  • $PropertyType<Obj, 'prop'> Obj['prop']
  • $ElementType<Obj, T> Obj[T]
  • $ElementType<$PropertyType<Obj, 'prop'>, T> Obj['prop'][T]

我们创建了一个 ESLint 规则,它会在 $ElementType$PropertyType 的使用上发出警告,并建议改用索引访问类型。它包含一个自动修复器,可以处理大多数情况。您只需在代码库中启用此规则并自动修复所有现有问题即可。

安装 eslint-plugin-fb-flow,并将 fb-flow 添加到您的 ESLint 插件列表中。然后在您的 ESLint 配置中启用该规则

'fb-flow/use-indexed-access-type': 1,