原始类型
JavaScript 有许多不同的原始类型 (MDN)
| 示例 | Flow 类型 | |
|---|---|---|
| 布尔值 | true 或 false | boolean |
| 字符串 | 'foo' | string |
| 数字 | 123 | number |
| 空 | null | null |
| 未定义 | undefined | void |
| 符号 (ES2015 中新增) | Symbol('foo') | symbol |
| 大整数 (ES2020 中新增) | 123n | bigint |
一些原始类型在语言中以字面量形式出现
1true;2"hello";33.14;4null;5undefined;63n;大整数和符号可以通过分别调用 BigInt 和 Symbol 来创建
1BigInt("2364023476023");2Symbol("hello");字面量的 Flow 类型为小写(与 JavaScript 的 typeof 表达式 的输出相匹配)
1function func(a: number, b: string, c: boolean, d: bigint) { /* ... */ }2
3func(3.14, "hello", true, 3n);一些字面量也可以用作 字面量类型
1function acceptTwo(x: 2) { /* ... */ }2
3acceptTwo(2); // Works!4acceptTwo(1); // Error! 4:11-4:11: Cannot call `acceptTwo` with `1` bound to `x` because number [1] is incompatible with number literal `2` [2]. [incompatible-call]
一些原始类型也可以包装为对象
注意:您可能永远不想使用包装对象变体。
1new Boolean(false);2new String("world");3new Number(42);包装对象的类型为大写(与其构造函数相同)
1function func(x: Number, y: String, z: Boolean) {2 // ...3}4
5func(new Number(42), new String("world"), new Boolean(false));这些包装对象很少使用。
布尔值
布尔值是 JavaScript 中的 true 和 false 值。Flow 中的 boolean 类型接受这些值。
1function acceptsBoolean(value: boolean) { /* ... */ }2
3acceptsBoolean(true); // Works!4acceptsBoolean(false); // Works!5
6acceptsBoolean("foo"); // Error! 6:16-6:20: Cannot call `acceptsBoolean` with `"foo"` bound to `value` because string [1] is incompatible with boolean [2]. [incompatible-call]
JavaScript 也可以隐式地将其他类型的转换为布尔值。
if (42) {} // 42 => true
if ("") {} // "" => false
Flow 理解这些强制转换,并将允许它们作为 if 语句的测试或其他条件上下文的一部分。
要将非布尔值显式转换为 boolean,可以使用 Boolean(x) 或 !!x。
1function acceptsBoolean(value: boolean) { /* ... */ }2
3acceptsBoolean(0); // Error! 4
5acceptsBoolean(Boolean(0)); // Works!6acceptsBoolean(!!0); // Works!3:16-3:16: Cannot call `acceptsBoolean` with `0` bound to `value` because number [1] is incompatible with boolean [2]. [incompatible-call]
您可以使用 typeof 检查将值 细化 为 boolean
1function acceptsBoolean(value: boolean) { /* ... */ }2
3function func(value: mixed) {4 if (typeof value === 'boolean') {5 acceptsBoolean(value); // Works: `value` is `boolean`6 }7}请记住,boolean 和 Boolean 是不同的类型。
boolean是一个字面量值,如true或false,或表达式(如a === b)的结果。Boolean是由全局new Boolean(x)构造函数创建的包装对象。您可能不想使用它!
数字
JavaScript 中的数字字面量是浮点数,例如 42 或 3.14。JavaScript 还认为 Infinity 和 NaN 是数字。这些由 number 类型表示。JavaScript 还具有单独的 大整数类型。
1function acceptsNumber(value: number) { /* ... */ }2
3acceptsNumber(42); // Works!4acceptsNumber(3.14); // Works!5acceptsNumber(NaN); // Works!6acceptsNumber(Infinity); // Works!7
8acceptsNumber("foo"); // Error! 9acceptsNumber(123n); // Error! 8:15-8:19: Cannot call `acceptsNumber` with `"foo"` bound to `value` because string [1] is incompatible with number [2]. [incompatible-call]9:15-9:18: Cannot call `acceptsNumber` with `123n` bound to `value` because bigint [1] is incompatible with number [2]. [incompatible-call]
您可以使用 typeof 检查将值 细化 为 number
1function acceptsNumber(value: number) { /* ... */ }2
3function func(value: mixed) {4 if (typeof value === 'number') {5 acceptsNumber(value); // Works: `value` is `number`6 }7}请记住,number 和 Number 是不同的类型。
number是一个字面量值,如42或3.14,或表达式(如parseFloat(x))的结果。Number是由全局new Number(x)构造函数创建的包装对象。您可能不想使用它!
字符串
字符串是 JavaScript 中的 "foo" 值。Flow 中的 string 类型接受这些值。
1function acceptsString(value: string) { /* ... */ }2
3acceptsString("foo"); // Works!4acceptsString(`template literal`); // Works!5
6acceptsString(false); // Error! 6:15-6:19: Cannot call `acceptsString` with `false` bound to `value` because boolean [1] is incompatible with string [2]. [incompatible-call]
JavaScript 隐式地将其他类型的转换为字符串,方法是将它们连接起来。
"foo" + 42; // "foo42"
"foo" + {}; // "foo[object Object]"
Flow 仅在将它们连接到字符串时才接受字符串和数字。
1"foo" + "foo"; // Works!2"foo" + 42; // Works!3`foo ${42}`; // Works!4
5"foo" + {}; // Error! 6"foo" + []; // Error! 7`foo ${[]}`; // Error! 5:1-5:10: Cannot use operator `+` with operands string [1] and object literal [2] [unsafe-addition]6:1-6:10: Cannot use operator `+` with operands string [1] and empty array literal [2] [unsafe-addition]7:8-7:9: Cannot coerce array literal to string because empty array literal [1] should not be coerced. [incompatible-type]
您必须明确地将其他类型转换为字符串。您可以使用 String 函数或使用另一种方法来将值字符串化。
1"foo" + String({}); // Works!2"foo" + [].toString(); // Works!3"" + JSON.stringify({}) // Works!您可以使用 typeof 检查将值 细化 为 string
1function acceptsString(value: string) { /* ... */ }2
3function func(value: mixed) {4 if (typeof value === 'string') {5 acceptsString(value); // Works: `value` is `string`6 }7}请记住,string 和 String 是不同的类型。
string是一个字面量值,如"foo",或表达式(如"" + 42)的结果。String是由全局new String(x)构造函数创建的包装对象。您可能不想使用它!
null 和 undefined
JavaScript 同时具有 null 和 undefined。Flow 将它们视为单独的类型:null 和 void(用于 undefined)。
1function acceptsNull(value: null) { /* ... */ }2
3acceptsNull(null); // Works!4acceptsNull(undefined); // Error! 5
6function acceptsUndefined(value: void) { /* ... */ }7
8acceptsUndefined(undefined); // Works!9acceptsUndefined(null); // Error! 4:13-4:21: Cannot call `acceptsNull` with `undefined` bound to `value` because undefined [1] is incompatible with null [2]. [incompatible-call]9:18-9:21: Cannot call `acceptsUndefined` with `null` bound to `value` because null [1] is incompatible with undefined [2]. [incompatible-call]
您可以使用相等性检查将值 细化 为 null 或 void
1function acceptsNull(value: null) { /* ... */ }2
3function func(value: mixed) {4 if (value === null) {5 acceptsNull(value); // Works: `value` is `null`6 }7}1function acceptsUndefined(value: void) { /* ... */ }2
3function func(value: mixed) {4 if (value === undefined) {5 acceptsUndefined(value); // Works: `value` is `void`6 }7}null 和 void 也出现在其他类型中
可能类型
可能类型 用于值可选且您可以通过在类型前面添加问号来创建它们的地方,例如 ?string 或 ?number。
?T 等效于 T | null | void。
1function acceptsMaybeString(value: ?string) { /* ... */ }2
3acceptsMaybeString("bar"); // Works!4acceptsMaybeString(undefined); // Works!5acceptsMaybeString(null); // Works!6acceptsMaybeString(); // Works!要细化,value == null 恰好检查 null 和 undefined。
阅读 可能类型文档 以了解更多详细信息。
可选对象属性
对象类型可以具有可选属性,其中问号 ? 位于属性名称之后。
{propertyName?: string}
除了它们的设置值类型之外,这些可选属性还可以是 void 或完全省略。但是,它们不能是 null。
1function acceptsObject(value: {foo?: string}) { /* ... */ }2
3acceptsObject({foo: "bar"}); // Works!4acceptsObject({foo: undefined}); // Works!5acceptsObject({}); // Works!6
7acceptsObject({foo: null}); // Error! 7:21-7:24: Cannot call `acceptsObject` with object literal bound to `value` because null [1] is incompatible with string [2] in property `foo`. [incompatible-call]
可选函数参数
函数可以具有可选参数,其中问号 ? 位于参数名称之后。
function func(param?: string) { /* ... */ }
除了它们的设置类型之外,这些可选参数还可以是 void 或完全省略。但是,它们不能是 null。
1function acceptsOptionalString(value?: string) { /* ... */ }2
3acceptsOptionalString("bar"); // Works!4acceptsOptionalString(undefined); // Works!5acceptsOptionalString(); // Works!6
7acceptsOptionalString(null); // Error! 7:23-7:26: Cannot call `acceptsOptionalString` with `null` bound to `value` because null [1] is incompatible with string [2]. [incompatible-call]
具有默认值的函数参数
函数参数也可以具有默认值。这是 ES2015 的一项功能。
function func(value: string = "default") { /* ... */ }
除了它们的设置类型之外,默认参数还可以是 void 或完全省略。但是,它们不能是 null。
1function acceptsOptionalString(value: string = "foo") { /* ... */ }2
3acceptsOptionalString("bar"); // Works!4acceptsOptionalString(undefined); // Works!5acceptsOptionalString(); // Works!6
7acceptsOptionalString(null); // Error! 7:23-7:26: Cannot call `acceptsOptionalString` with `null` bound to `value` because null [1] is incompatible with string [2]. [incompatible-call]
符号
符号是使用 JavaScript 中的 Symbol() 创建的。Flow 对符号有基本支持,使用 symbol 类型。
1function acceptsSymbol(value: symbol) { /* ... */ }2
3acceptsSymbol(Symbol()); // Works!4acceptsSymbol(Symbol.isConcatSpreadable); // Works!5
6acceptsSymbol(false); // Error! 6:15-6:19: Cannot call `acceptsSymbol` with `false` bound to `value` because boolean [1] is incompatible with symbol [2]. [incompatible-call]
您可以使用 typeof 检查将值 细化 为 symbol
1function acceptsSymbol(value: symbol) { /* ... */ }2
3function func(value: mixed) {4 if (typeof value === 'symbol') {5 acceptsSymbol(value); // Works: `value` is `symbol`6 }7}大整数
大整数可用于表示任意精度的整数。换句话说,它们可以存储作为 number 存储起来过大的整数。
bigint 字面量只是一个 number 字面量,以及一个 n 后缀。
请注意,bigint 和 number 是不兼容的类型。也就是说,bigint 不能在需要 number 的地方使用,反之亦然。
1function acceptsBigInt(value: bigint) { /* ... */ }2
3acceptsBigInt(42n); // Works!4acceptsBigInt(42); // Error! 4:15-4:16: Cannot call `acceptsBigInt` with `42` bound to `value` because number [1] is incompatible with bigint [2]. [incompatible-call]
您可以使用 typeof 检查将值 细化 为 bigint
1function acceptsBigInt(value: bigint) { /* ... */ }2
3function func(value: mixed) {4 if (typeof value === 'bigint') {5 acceptsBigInt(value); // Works: `value` is `bigint`6 }7}