索引存取類型
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`
存取陣列類型的元素,透過取得陣列索引 (為 數字
) 的類型
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
。如果你有長串巢狀可選存取,如果你不希望在結果類型中出現 void
,你可以用 $NonMaybeType<...>
包住整個東西。
範例
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
。但是,如果你的物件類型不可為空,你就不需要使用可選索引存取類型,而應該只使用一般索引存取類型。
採用
若要使用索引存取類型,你需要升級你的基礎架構,以便它支援語法
flow
和flow-parser
:0.155prettier
: 2.3.2babel
: 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,