可选类型
您可以使用 ?
前缀一个类型,使其成为与 null
和 void
的 联合类型:?T
等效于联合类型 T | null | void
。
例如,?number
等效于 number | null | void
,并允许数字、null
和 undefined
作为值。它“可能”是一个数字。
1function acceptsMaybeNumber(value: ?number) {2 // ...3}4
5acceptsMaybeNumber(42); // Works!6acceptsMaybeNumber(); // Works! (implicitly undefined)7acceptsMaybeNumber(undefined); // Works!8acceptsMaybeNumber(null); // Works!9acceptsMaybeNumber("42"); // Error!
9:20-9:23: Cannot call `acceptsMaybeNumber` with `"42"` bound to `value` because string [1] is incompatible with number [2]. [incompatible-call]
在对象的情况下,缺少属性与显式 undefined
属性不同。
1function acceptsMaybeProp({value}: {value: ?number}) {2 // ...3}4
5acceptsMaybeProp({value: undefined}); // Works!6acceptsMaybeProp({}); // Error!
6:18-6:19: Cannot call `acceptsMaybeProp` with object literal bound to the first parameter because property `value` is missing in object literal [1] but exists in object type [2]. [prop-missing]
如果您想允许缺少属性,请使用 可选属性 语法,其中 ?
放在冒号之前。也可以将两种语法结合起来,用于可选的可选类型,例如 {value?: ?number}
。
细化可选类型
假设我们有类型 ?number
,如果我们想将该值用作 number
,我们需要先检查它是否不是 null
或 undefined
。
1function acceptsMaybeNumber(value: ?number): number {2 if (value !== null && value !== undefined) {3 return value * 2;4 }5 return 0;6}
您可以使用单个 != null
检查来简化对 null
和 undefined
的两次检查,这将同时执行这两项检查。
1function acceptsMaybeNumber(value: ?number): number {2 if (value != null) {3 return value * 2;4 }5 return 0;6}
大多数双等号检查在 JavaScript 中是不鼓励的,但上述模式是安全的(它检查的是确切的 null
和 undefined
)。
您也可以反过来,检查该值是否具有 number
类型,然后再使用它。
1function acceptsMaybeNumber(value: ?number): number {2 if (typeof value === 'number') {3 return value * 2;4 }5 return 0;6}
但是,类型细化可能会丢失。例如,在细化对象属性的类型后调用函数将使这种细化失效。请参阅 细化失效 文档以了解更多详细信息,了解 Flow 为什么这样工作以及如何避免这种常见陷阱。