From 73f0d319067f144777941a2f7ed734c3de320318 Mon Sep 17 00:00:00 2001 From: jamashita Date: Fri, 27 Dec 2024 20:36:53 +0900 Subject: [PATCH 1/3] =?UTF-8?q?docs:=20=E2=9C=8F=EF=B8=8F=20satisfies?= =?UTF-8?q?=E3=81=AB=E3=81=A4=E3=81=84=E3=81=A6=E8=A8=98=E8=BF=B0=E3=82=92?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../values-types-variables/satisfies.md | 189 ++++++++++++++++++ sidebars.js | 1 + 2 files changed, 190 insertions(+) create mode 100644 docs/reference/values-types-variables/satisfies.md diff --git a/docs/reference/values-types-variables/satisfies.md b/docs/reference/values-types-variables/satisfies.md new file mode 100644 index 00000000..9f446e66 --- /dev/null +++ b/docs/reference/values-types-variables/satisfies.md @@ -0,0 +1,189 @@ +--- +sidebar_label: satisfies演算子 「satisfies operator」 +--- + +# satisfies演算子「satisfies operator」 + +`satisfies T`(`T`は型)は、変数宣言時に使用する演算子で、その値が型`T`を満たすことを検証します。この演算子は型の絞り込みを保持したまま型チェックを行える特徴があります。 + +`as const`と異なり、`satisfies`はその後に型を要求します。単独で使用することはできません。 + +## 型アノテーションと同じようにできること + +変数宣言のときに変数名の後ろに`: T`と書くことを型アノテーションといいます。こちらは変数宣言時にその変数が型`T`を満たすことを検証します。 + +というと`satisfies T`の機能が型アノテーションとまったく同じように見えます。実際次の例はまったく同じ働きをします。 + +```ts twoslash +type Pokemon = { + name: string; + no: number; + genre: string; + height: number; + weight: number; +}; +const pikachu: Pokemon = { + name: "pikachu", + no: 25, + genre: "mouse pokémon", + height: 0.4, + weight: 6.0, +}; +const raichu = { + name: "raichu", + no: 26, + genre: "mouse pokémon", + height: 0.8, + weight: 30.0, +} satisfies Pokemon; +``` + +どちらも宣言した型に沿わない型を与えるとエラーが発生します。 +また、存在しないプロパティを追加することもできません。 + +```ts twoslash +type Pokemon = { + name: string; + no: number; + genre: string; + height: number; + weight: number; +}; + +// ---cut--- +// @errors: 2322 2353 +const pikachu: Pokemon = { + name: "pikachu", + no: 25, + genre: "mouse pokémon", + height: "0.4m", + weight: "6.0kg", +}; +const raichu = { + name: "raichu", + no: 26, + genre: "mouse pokémon", + height: "0.8m", + weight: "30.0kg", +} satisfies Pokemon; +``` + +```ts twoslash +type Pokemon = { + name: string; + no: number; + genre: string; + height: number; + weight: number; +}; + +// ---cut--- +// @errors: 2353 +const pikachu: Pokemon = { + name: "pikachu", + no: 25, + genre: "mouse pokémon", + height: 0.4, + weight: 6.0, + type: "electric", +}; +const raichu = { + name: "raichu", + no: 26, + genre: "mouse pokémon", + height: 0.8, + weight: 30.0, + type: "electric", +} satisfies Pokemon; +``` + +## 型アノテーションとちがうこと + +`satisfies`の最大の特徴は、型`T`にユニオン型が含まれる場合でも、実際の値に基づいて型を絞り込むことができる点です。型アノテーションでは失われてしまう型の情報を保持できます。 +主にオブジェクトリテラルや配列で使用しますが、プリミティブ型でも使用できます。 + +```ts twoslash +const array1: (string | number)[] = [1, 2, 3]; +// ^? +const array2 = [1, 2, 3] satisfies (string | number)[]; +// ^? +``` + +ユニオン型の配列の場合は期待する結果にならないときもあります。 + +```ts twoslash +const array1: (string | number)[] = [1, "2", 3]; +// ^? +const array2 = [1, "2", 3] satisfies (string | number)[]; +// ^? +``` + +タプル型の場合は個々に型の絞り込みを行います。 + +```ts twoslash +const tuple1: [string | number, string | number, string | number] = [1, "2", 3]; +// ^? +const tuple2 = [1, "2", 3] satisfies [ + string | number, + string | number, + string | number +]; +// ^? +``` + +オブジェクトのプロパティにあるユニオン型にも効果があります。 + +```ts twoslash +type SuccessResponse = { + success: true; + data: object; +}; +type ErrorResponse = { + success: false; + error: string; +}; +type ApiResponse = SuccessResponse | ErrorResponse; + +const res1: ApiResponse = { + // ^? + success: false, + error: "too many requests", +}; +const res2 = { + // ^? + success: false, + error: "too many requests", +} satisfies ApiResponse; +``` + +## as constと組み合わせる + +`as const`と組み合わせて`as const satisfies T`と書くことができます。 + +これは型`T`を満たしていることを示した上で絞り込みを行い、さらにリテラル型にしてreadonlyにするという`as const`と`satisfies`の機能をあわせ持っています。 + +```ts twoslash +type SuccessResponse = { + success: true; + data: object; +}; +type ErrorResponse = { + success: false; + error: string; +}; +type ApiResponse = SuccessResponse | ErrorResponse; +// ---cut--- +const array = [1, "2", 3] as const satisfies (string | number)[]; +// ^? +const tuple = [1, "2", 3] as const satisfies [ + string | number, + string | number, + string | number +]; +// ^? +const res = { + // ^? + success: false, + error: "too many requests", +} as const satisfies ApiResponse; +``` diff --git a/sidebars.js b/sidebars.js index 0d45e410..2fec7f9d 100644 --- a/sidebars.js +++ b/sidebars.js @@ -167,6 +167,7 @@ module.exports = { "reference/values-types-variables/type-alias", "reference/values-types-variables/type-assertion-as", "reference/values-types-variables/const-assertion", + "reference/values-types-variables/satisfies", "reference/values-types-variables/definite-assignment-assertion", "reference/values-types-variables/typeof-operator", "reference/values-types-variables/equality", From 1340a9b138b2e661e32ca743ad8937efb7714727 Mon Sep 17 00:00:00 2001 From: jamashita Date: Fri, 27 Dec 2024 20:55:43 +0900 Subject: [PATCH 2/3] =?UTF-8?q?docs:=20=E2=9C=8F=EF=B8=8F=20=E7=A4=BA?= =?UTF-8?q?=E3=81=99=20->=20=E6=A4=9C=E8=A8=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/reference/values-types-variables/satisfies.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/reference/values-types-variables/satisfies.md b/docs/reference/values-types-variables/satisfies.md index 9f446e66..ac065cfb 100644 --- a/docs/reference/values-types-variables/satisfies.md +++ b/docs/reference/values-types-variables/satisfies.md @@ -160,7 +160,7 @@ const res2 = { `as const`と組み合わせて`as const satisfies T`と書くことができます。 -これは型`T`を満たしていることを示した上で絞り込みを行い、さらにリテラル型にしてreadonlyにするという`as const`と`satisfies`の機能をあわせ持っています。 +これは型`T`を満たしていることを検証した上で絞り込みを行い、さらにリテラル型にしてreadonlyにするという`as const`と`satisfies`の機能をあわせ持っています。 ```ts twoslash type SuccessResponse = { From 7ec30ba6067487a220c6266fcb00a624480c32d2 Mon Sep 17 00:00:00 2001 From: jamashita Date: Fri, 27 Dec 2024 21:24:30 +0900 Subject: [PATCH 3/3] =?UTF-8?q?docs:=20=E2=9C=8F=EF=B8=8F=20add=20prettier?= =?UTF-8?q?-ignore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/reference/values-types-variables/satisfies.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/reference/values-types-variables/satisfies.md b/docs/reference/values-types-variables/satisfies.md index ac065cfb..6a5fa31d 100644 --- a/docs/reference/values-types-variables/satisfies.md +++ b/docs/reference/values-types-variables/satisfies.md @@ -121,19 +121,21 @@ const array2 = [1, "2", 3] satisfies (string | number)[]; タプル型の場合は個々に型の絞り込みを行います。 ```ts twoslash +// prettier-ignore const tuple1: [string | number, string | number, string | number] = [1, "2", 3]; // ^? const tuple2 = [1, "2", 3] satisfies [ + // ^? string | number, string | number, string | number ]; -// ^? ``` オブジェクトのプロパティにあるユニオン型にも効果があります。 ```ts twoslash +// prettier-ignore type SuccessResponse = { success: true; data: object; @@ -163,6 +165,7 @@ const res2 = { これは型`T`を満たしていることを検証した上で絞り込みを行い、さらにリテラル型にしてreadonlyにするという`as const`と`satisfies`の機能をあわせ持っています。 ```ts twoslash +// prettier-ignore type SuccessResponse = { success: true; data: object; @@ -176,11 +179,12 @@ type ApiResponse = SuccessResponse | ErrorResponse; const array = [1, "2", 3] as const satisfies (string | number)[]; // ^? const tuple = [1, "2", 3] as const satisfies [ + // ^? string | number, string | number, string | number ]; -// ^? + const res = { // ^? success: false,