Toán tử satisfies (satisfies operator)
satisfies T (T là type) là toán tử sử dụng khi khai báo biến, dùng để kiểm tra xem giá trị đó có thỏa mãn type T không. Đặc điểm của toán tử này là có thể thực hiện type check trong khi vẫn giữ được việc thu hẹp type.
Khác với as const, satisfies yêu cầu một type đi sau nó. Không thể sử dụng đơn lẻ.
Những điều giống với type annotation
Việc viết : T sau tên biến khi khai báo biến được gọi là type annotation. Type annotation kiểm tra xem biến đó có thỏa mãn type T khi khai báo biến.
Nghe có vẻ chức năng của satisfies T hoàn toàn giống với type annotation. Thực tế, ví dụ sau hoạt động hoàn toàn giống nhau.
tstypePokemon = {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 ;
tstypePokemon = {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 ;
Cả hai đều phát sinh lỗi nếu gán type không theo đúng type đã khai báo.
Ngoài ra, cũng không thể thêm property không tồn tại.
tsconstpikachu :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 ;
tsconstpikachu :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 ;
tsconstpikachu :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 ;
tsconstpikachu :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 ;
Những điều khác với type annotation
Đặc điểm lớn nhất của satisfies là khi type T chứa union type, nó vẫn có thể thu hẹp type dựa trên giá trị thực tế. Có thể giữ lại thông tin type mà với type annotation sẽ bị mất đi.
Chủ yếu sử dụng với object literal hoặc array, nhưng cũng có thể sử dụng với primitive type.
tsconstarray1 : (string | number)[] = [1, 2, 3];constarray2 = [1, 2, 3] satisfies (string | number)[];
tsconstarray1 : (string | number)[] = [1, 2, 3];constarray2 = [1, 2, 3] satisfies (string | number)[];
Với array của union type, đôi khi kết quả không như mong đợi.
tsconstarray1 : (string | number)[] = [1, "2", 3];constarray2 = [1, "2", 3] satisfies (string | number)[];
tsconstarray1 : (string | number)[] = [1, "2", 3];constarray2 = [1, "2", 3] satisfies (string | number)[];
Với tuple type, việc thu hẹp type được thực hiện cho từng phần tử.
tsconsttuple1 : [string | number, string | number, string | number] = [1, "2", 3];consttuple2 = [1, "2", 3] satisfies [string | number,string | number,string | number];
tsconsttuple1 : [string | number, string | number, string | number] = [1, "2", 3];consttuple2 = [1, "2", 3] satisfies [string | number,string | number,string | number];
Cũng có hiệu quả với union type trong property của object.
tstypeSuccessResponse = {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 ;
tstypeSuccessResponse = {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 ;
Kết hợp với as const
Có thể kết hợp với as const và viết as const satisfies T.
Điều này kết hợp chức năng của as const và satisfies: kiểm tra xem có thỏa mãn type T không, thực hiện thu hẹp type, và thêm vào đó làm thành literal type và readonly.
tsconstarray = [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 ;
tsconstarray = [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 ;