Closed4
[TypeScript] 定数の配列に as const と satisfies をつける
定数の配列を宣言する
下記のように配列を宣言をすると、stringの配列になる。
要素の取得時にもstringとなってしまい不便。
また配列の更新も可能なため、定数としてよろしくない。
// fruits: string[] に推論される
const fruits = ['apple', 'banana', 'orange'];
// fruit: string | undefined に推論される
const fruit = fruits[0];
// 自由に編集も可能
fruits[10] = 'melon';
const fruit = fruits[0];
がundefinedも考慮するようになるのは、下記tsconfigの noUncheckedIndexedAccess
を設定する必要あり。
as const で定義する
as constをつけるとreadonlyになり、かつ型が狭まりタプル型になる。
// fruits: readonly ["apple", "banana", "orange"]
const fruits = ['apple', 'banana', 'orange'] as const;
// fruit: "apple"
const fruit = fruits[0];
// コンパイルエラー
// readonlyのため、編集不可
fruits[10] = 'melon';
const assertions
as const のみの場合の問題点
['apple', 'banana', 'orange'] as const
const assertions で厳格になるのは代入後からのため、機能拡張などで ['apple', 'banana', 'orange']
を編集する際に、中身がstringの配列ということを定義したい。
下記では、numberの1を含んだ配列としての定義になってしまう。
// fruits: readonly ["apple", "banana", "orange", 1]
const fruits = ['apple', 'banana', 'orange', 1] as const;
satisfies で定義する
下記のように定義する。
その場合、配列にstring以外を定義した場合はコンパイルエラーとなる。
// コンパイルエラー。numberの1を含んでいるため
const fruits = ['apple', 'banana', 'orange', 1] as const satisfies readonly string[];
// fruits: readonly ["apple", "banana", "orange"]
const fruits = ['apple', 'banana', 'orange'] as const satisfies readonly string[];
The satisfies Operator
上記の例ではわかりやすく配列のみ記述しているが、オブジェクトでも同様の挙動となる。
オブジェクトの方がsatisfies
の恩恵をより受けやすい
// person: {
// name: string;
// age: number;
// }
const person = {
name: '山田太郎',
age: 20,
};
// const person: {
// readonly name: "山田太郎";
// readonly age: 20;
// }
const person = {
name: '山田太郎',
age: 20,
} as const;
type Person = {
name: string;
age: number;
};
// const person: {
// readonly name: "山田太郎";
// readonly age: 20;
// }
const person = {
name: '山田太郎',
age: 20,
} as const satisfies Person
// コンパイルエラー
// Personのageの型はnumberであるが、stringで定義しようとしているため
const person = {
name: '山田太郎',
age: '20',
} as const satisfies Person
このスクラップは2023/07/25にクローズされました