メインコンテンツへスキップ

プリミティブ型

JavaScriptにはいくつかの異なるプリミティブ型があります (MDN)

Flow型
ブール値true または falseboolean
文字列'foo'string
数値123number
Nullnullnull
Undefinedundefinedvoid
シンボル (ES2015から追加)Symbol('foo')symbol
BigInt (ES2020から追加)123nbigint

いくつかのプリミティブ型は、言語においてリテラル値として現れます。

1true;2"hello";33.14;4null;5undefined;63n;

BigIntとシンボルは、それぞれ`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には、別個のBigInt型もあります。

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)`コンストラクタによって作成されるラッパーオブジェクトです。おそらくこれは使用したくないでしょう!

nullundefined

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`は他の型にも現れます。

Maybe型

Maybe型は、値がオプションの場合に使用でき、型名の前に疑問符を付けることで作成できます(例:`?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`の両方を正確にチェックします。

詳細はMaybe型のドキュメントを参照してください。

オプションのオブジェクトプロパティ

オブジェクト型には、プロパティ名の後に疑問符`?`を付けることで、オプションのプロパティを含めることができます。

{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}

BigInt

BigIntは、任意精度の整数を表すために使用できます。つまり、`number`として格納するには大きすぎる整数を格納できます。

`bigint`リテラルは、`n`接尾辞が付いた`number`リテラルです。

`bigint`と`number`は互換性のない型であることに注意してください。つまり、`number`が期待される場所に`bigint`を使用することはできず、その逆もできません。

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}