型キャスト式
関数や変数などを用いずに型を表明したい場合があります。このため、Flowは様々な方法で使用できるインライン型キャスト式の構文をサポートしています。
型キャスト式の構文
型キャスト式を作成するには、キーワード`as`を使用して値を型にキャストします。
value as Type
これは「as式」とも呼ばれます。
Flowバージョン0.229より前では、従来の構文 `(value: Type)` が使用されていました。
型キャスト式は、式が現れる場所であればどこにでも現れることができます。
let val = value as Type;
let obj = {prop: value as Type};
let arr = [value as Type, value as Type] as Array<Type>;
値自体も式にすることができます。
12 + 2 as number;
`as`演算子は`in`および`instanceof`と同じ優先順位を持つことに注意してください。このため、式を括弧で囲む必要がある場合があります。
11 === 1 as boolean; // Error! 2// Above same as `1 === (1 as boolean)3
4(1 === 1) as boolean; // Works!
1:7-1:7: Cannot cast `1` to boolean because number [1] is incompatible with boolean [2]. [incompatible-cast]
さらに、式文のコンテキストでは、文として曖昧に解析される可能性のある式は括弧が必要です。
1({a: 1}) as {a: number}; // Needs parens to disambiguate from block statement2const x = {a: 1} as {a: number}; // No parens needed, as not in expression statement context
型を取り除くと、残るのは値だけです。
value as Type;
は以下に変換されます。
value;
型アサーション
型キャスト式を使用すると、値が特定の型であることを表明できます。
1let value = 42;2
3value as 42; // Works!4value as number; // Works!5value as string; // Error!
5:1-5:5: Cannot cast `value` to string because number [1] is incompatible with string [2]. [incompatible-cast]
この方法で型を表明することは、他の場所での型と同じように機能します。
型キャスト
型キャスト式を記述する場合、その式の結果は、指定された型を持つ値です。結果の値を保持すると、新しい型が設定されます。
1let value = 42;2
3value as 42; // Works!4value as number; // Works!5
6let newValue = value as number;7
8newValue as 42; // Error! 9newValue as number; // Works!
8:1-8:8: Cannot cast `newValue` to number literal `42` because number [1] is incompatible with number literal `42` [2]. [incompatible-cast]
安全でないダウンキャストは許可されていません。
1const fooObj = {foo: 1};2const otherObj = fooObj as {foo: number, bar: string}; // ERROR
2:18-2:23: Cannot cast `fooObj` to object type because property `bar` is missing in object literal [1] but exists in object type [2]. [prop-missing]
`as`構文の採用
型キャストに`as`キーワードを使用するには、構文をサポートするようにインフラストラクチャをアップグレードする必要があります。
- FlowおよびFlowパーサー:0.229+
- Prettier:3.1+
- Babel:babel-plugin-syntax-hermes-parserプラグインバージョン0.19+を使用してください。詳細については、Babelガイドを参照してください。
- ESLint:hermes-eslintプラグインバージョン0.19+を使用してください。詳細については、ESLintガイドを参照してください。
新しいキャスト構文(`as`)への移行方法の詳細については、ブログ記事をご覧ください。
型キャスト式の使用
**注意:** 型キャスト式の使用方法を示すために、簡略化された例を紹介します。この例は、実際には適切に解決されていません。
`any`を通じた型キャスト
型キャストは他のすべての型注釈と同じように機能するため、値をより具体的な型にキャストすることしかできません。型を変更したり、より具体的な型にすることはできません。
ただし、anyを使用して、任意の型にキャストできます。
1let value = 42;2
3value as number; // Works!4value as string; // Error! 5
6let newValue = value as any as string;7
8newValue as number; // Error! 9newValue as string; // Works!
4:1-4:5: Cannot cast `value` to string because number [1] is incompatible with string [2]. [incompatible-cast]8:1-8:8: Cannot cast `newValue` to number because string [1] is incompatible with number [2]. [incompatible-cast]
値を`any`にキャストすることで、任意の型にキャストできます。
これは安全ではなく、推奨されません。しかし、型付けが非常に困難または不可能な値で何かを行い、結果が目的の型を持つようにしたい場合に役立つことがあります。
たとえば、オブジェクトを複製するための次の関数です。
1function cloneObject(obj: any) {2 const clone: {[string]: mixed} = {};3
4 Object.keys(obj).forEach(key => {5 clone[key] = obj[key];6 });7
8 return clone;9}
別のオブジェクトに基づいて新しいオブジェクトを作成しているため、これの型を作成するのは困難です。
`any`を介してキャストする場合、より有用な型を返すことができます。
1function cloneObject<T: {+[key: string]: mixed }>(obj: T): T {2 const clone: {[string]: mixed} = {};3
4 Object.keys(obj).forEach(key => {5 clone[key] = obj[key];6 });7
8 return clone as any as T;9}10
11const clone = cloneObject({12 foo: 1,13 bar: true,14 baz: 'three'15});16
17clone.foo as 1; // Works!18clone.bar as true; // Works!19clone.baz as 'three'; // Works!
従来のキャスト構文
バージョン0.229より前では、`value`の周りに型キャスト式を作成するには、コロン`:`と`Type`を追加し、式を括弧`(` `)`で囲みます。
(value: Type)
**注意:** 他の構文とのあいまいさを避けるために、括弧が必要です。