はじめに
この記事は【TypeScript】+【Conditional Types】についての備忘録である。
【Conditional Types】とは
【Conditional Types】は日本語では条件付き型、型の条件分岐、条件型などと呼ばれ、三項演算子のように ?
と :
を使ってT extends U ? X : Y
のように書く。
以下のサンプルコードだと型は true
になる。
type IsString<T> = T extends string ? true : false;
const a: IsString<"a"> = true;
再帰的に Readonly<T> を適用する方法
Readonly<T>
はそのオブジェクトの直下のプロパティを読み取り専用にしますが、ネストしたオブジェクトのプロパティは読み取り専用にしない。
次のようなオブジェクトがあると仮定する。
type Person = {
name: string;
age: number;
address: {
country: string;
city: string;
};
};
このとき Readonly<Person>
では address
プロパティ自体は読み取り専用になっており書き換えることはできないが、address
のプロパティの country
と city
は読み取り専用になっていので上書きが可能である。
const kimberley: Readonly<Person> = {
name: "Kimberley",
age: 24,
address: {
country: "Canada",
city: "Vancouver",
},
};
// 代入できない
kimberley.name = "Kim";
// 代入できない
kimberley.age = 25;
// 代入できない
kimberley.address = {
country: "United States",
city: "Seattle",
};
// 代入できる
kimberley.address.country = "United States";
// 代入できる
kimberley.address.city = "Seattle";
これを解決するには Readonly<T>
を再帰的に適用する必要がある。
このような場合に Mapped Types
と Conditional Types
を組み合わせて使う。
type Freeze<T> = Readonly<{
[P in keyof T]: T[P] extends object ? Freeze<T[P]> : T[P];
}>;
コメント