satisfies演算子「satisfies operator」
satisfies T
(T
は型)は、変数宣言時に使用する演算子で、その値が型T
を満たすことを検証します。この演算子は型の絞り込みを保持したまま型チェックを行える特徴があります。
as const
と異なり、satisfies
はその後に型を要求します。単独で使用することはできません。
型アノテーションと同じようにできること
変数宣言のときに変数名の後ろに: T
と書くことを型アノテーションといいます。こちらは変数宣言時にその変数が型T
を満たすことを検証します。
というとsatisfies T
の機能が型アノテーションとまったく同じように見えます。実際次の例はまったく同じ働きをします。
ts
typePokemon = {name : string;no : number;genre : string;height : number;weight : number;};constpikachu :Pokemon = {name : "pikachu",no : 25,genre : "mouse pokémon",height : 0.4,weight : 6.0,};constraichu = {name : "raichu",no : 26,genre : "mouse pokémon",height : 0.8,weight : 30.0,} satisfiesPokemon ;
ts
typePokemon = {name : string;no : number;genre : string;height : number;weight : number;};constpikachu :Pokemon = {name : "pikachu",no : 25,genre : "mouse pokémon",height : 0.4,weight : 6.0,};constraichu = {name : "raichu",no : 26,genre : "mouse pokémon",height : 0.8,weight : 30.0,} satisfiesPokemon ;
どちらも宣言した型に沿わない型を与えるとエラーが発生します。
また、存在しないプロパティを追加することもできません。
ts
constpikachu :Pokemon = {name : "pikachu",no : 25,genre : "mouse pokémon",Type 'string' is not assignable to type 'number'.2322Type 'string' is not assignable to type 'number'.: "0.4m", height Type 'string' is not assignable to type 'number'.2322Type 'string' is not assignable to type 'number'.: "6.0kg", weight };constraichu = {name : "raichu",no : 26,genre : "mouse pokémon",Type 'string' is not assignable to type 'number'.2322Type 'string' is not assignable to type 'number'.: "0.8m", height Type 'string' is not assignable to type 'number'.2322Type 'string' is not assignable to type 'number'.: "30.0kg", weight } satisfiesPokemon ;
ts
constpikachu :Pokemon = {name : "pikachu",no : 25,genre : "mouse pokémon",Type 'string' is not assignable to type 'number'.2322Type 'string' is not assignable to type 'number'.: "0.4m", height Type 'string' is not assignable to type 'number'.2322Type 'string' is not assignable to type 'number'.: "6.0kg", weight };constraichu = {name : "raichu",no : 26,genre : "mouse pokémon",Type 'string' is not assignable to type 'number'.2322Type 'string' is not assignable to type 'number'.: "0.8m", height Type 'string' is not assignable to type 'number'.2322Type 'string' is not assignable to type 'number'.: "30.0kg", weight } satisfiesPokemon ;
ts
constpikachu :Pokemon = {name : "pikachu",no : 25,genre : "mouse pokémon",height : 0.4,weight : 6.0,Object literal may only specify known properties, and 'type' does not exist in type 'Pokemon'.2353Object literal may only specify known properties, and 'type' does not exist in type 'Pokemon'.: "electric", type };constraichu = {name : "raichu",no : 26,genre : "mouse pokémon",height : 0.8,weight : 30.0,Object literal may only specify known properties, and 'type' does not exist in type 'Pokemon'.2353Object literal may only specify known properties, and 'type' does not exist in type 'Pokemon'.: "electric", type } satisfiesPokemon ;
ts
constpikachu :Pokemon = {name : "pikachu",no : 25,genre : "mouse pokémon",height : 0.4,weight : 6.0,Object literal may only specify known properties, and 'type' does not exist in type 'Pokemon'.2353Object literal may only specify known properties, and 'type' does not exist in type 'Pokemon'.: "electric", type };constraichu = {name : "raichu",no : 26,genre : "mouse pokémon",height : 0.8,weight : 30.0,Object literal may only specify known properties, and 'type' does not exist in type 'Pokemon'.2353Object literal may only specify known properties, and 'type' does not exist in type 'Pokemon'.: "electric", type } satisfiesPokemon ;
型アノテーションとちがうこと
satisfies
の最大の特徴は、型T
にユニオン型が含まれる場合でも、実際の値に基づいて型を絞り込むことができる点です。型アノテーションでは失われてしまう型の情報を保持できます。
主にオブジェクトリテラルや配列で使用しますが、プリミティブ型でも使用できます。
ts
constarray1 : (string | number)[] = [1, 2, 3];constarray2 = [1, 2, 3] satisfies (string | number)[];
ts
constarray1 : (string | number)[] = [1, 2, 3];constarray2 = [1, 2, 3] satisfies (string | number)[];
ユニオン型の配列の場合は期待する結果にならないときもあります。
ts
constarray1 : (string | number)[] = [1, "2", 3];constarray2 = [1, "2", 3] satisfies (string | number)[];
ts
constarray1 : (string | number)[] = [1, "2", 3];constarray2 = [1, "2", 3] satisfies (string | number)[];
タプル型の場合は個々に型の絞り込みを行います。
ts
consttuple1 : [string | number, string | number, string | number] = [1, "2", 3];consttuple2 = [1, "2", 3] satisfies [string | number,string | number,string | number];
ts
consttuple1 : [string | number, string | number, string | number] = [1, "2", 3];consttuple2 = [1, "2", 3] satisfies [string | number,string | number,string | number];
オブジェクトのプロパティにあるユニオン型にも効果があります。
ts
typeSuccessResponse = {success : true;data : object;};typeErrorResponse = {success : false;error : string;};typeApiResponse =SuccessResponse |ErrorResponse ;constres1 :ApiResponse = {success : false,error : "too many requests",};constres2 = {success : false,error : "too many requests",} satisfiesApiResponse ;
ts
typeSuccessResponse = {success : true;data : object;};typeErrorResponse = {success : false;error : string;};typeApiResponse =SuccessResponse |ErrorResponse ;constres1 :ApiResponse = {success : false,error : "too many requests",};constres2 = {success : false,error : "too many requests",} satisfiesApiResponse ;
as constと組み合わせる
as const
と組み合わせてas const satisfies T
と書くことができます。
これは型T
を満たしていることを検証した上で絞り込みを行い、さらにリテラル型にしてreadonlyにするというas const
とsatisfies
の機能をあわせ持っています。
ts
constarray = [1, "2", 3] asconst satisfies (string | number)[];consttuple = [1, "2", 3] asconst satisfies [string | number,string | number,string | number];constres = {success : false,error : "too many requests",} asconst satisfiesApiResponse ;
ts
constarray = [1, "2", 3] asconst satisfies (string | number)[];consttuple = [1, "2", 3] asconst satisfies [string | number,string | number,string | number];constres = {success : false,error : "too many requests",} asconst satisfiesApiResponse ;