Skip to main content

索引访问类型

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

¥Flow’s Indexed Access Types allow you to get the type of a property from an object, array, or tuple type.

用法

¥Usage

访问对象类型的属性:

¥Access an object type's property:

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)处的类型来访问数组类型的元素:

¥Access an array type's element, by getting the type at the array's indices (which are numbers):

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

访问元组类型的元素:

¥Access a tuple type's elements:

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

索引可以是一个并集,包括调用 $Keys<...> 的结果:

¥The index can be a union, including the result of calling $Keys<...>:

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

该索引也可以是通用的:

¥The index can also be a generic:

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

你可以嵌套这些访问:

¥You can nest these accesses:

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

可选索引访问类型

¥Optional Indexed Access Types

可选索引访问类型的工作方式类似于可选链接。它们允许你访问可为 null 的对象类型的属性。如果你之前这样做过:

¥Optional Indexed Access Types work like optional chaining. They allow you to access properties from nullable object types. If before you did:

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

你现在可以执行以下操作:

¥You can now do:

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

与可选链接一样,可选索引访问类型的结果类型包括 void。如果你有一长串嵌套可选访问,并且你不希望结果类型中出现 void,则可以用 $NonMaybeType<...> 封装整个内容。

¥Like optional chaining, the resulting types of Optional Indexed Access Types include void. If you have a long chain of nested optional accesses, you can wrap the entire thing with a $NonMaybeType<...> if you don’t want void in your resulting type.

示例:

¥Example:

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'];

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

¥There is one small difference between optional chaining and Optional Indexed Access Types. If the object type you access is not nullable, the resulting type in optional chaining will not include void. With Optional Indexed Access Types, for implementation reasons, the resulting type will always include void. However, if your object type is not nullable then you don’t need to use an Optional Indexed Access Type, but should just use a regular Indexed Access Type.

采纳

¥Adoption

要使用索引访问类型,你需要升级基础架构以使其支持语法:

¥To use Indexed Access Types, you need to upgrade your infrastructure so that it supports the syntax:

  • flowflow-parser:0.155

    ¥flow and flow-parser: 0.155

  • prettier:2.3.2

  • babel:7.14

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

¥Indexed Access Types are a replacement for the $PropertyType and $ElementType utility types. If you're familiar with those utility types already, here is a quick conversion guide:

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

  • $ElementType<Obj, T>Obj[T]

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

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

¥We have created an ESLint rule that warns on $ElementType and $PropertyType usage and recommends Indexed Access Types instead. It includes an auto-fixer that can handle most cases. You can simply enable this rule on your codebase and autofix all existing issues.

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

¥Install eslint-plugin-fb-flow, and add fb-flow to your ESLint plugin list. Then enable the rule in your ESLint config:

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