TypeScript: マップ型の -readonly / -? で修飾子を外す
マップ型で -readonly を付けると全キーの readonly を外し、-? を付けると全キーの「省略可能」を外せる。
どんな時に使う?
- ライブラリ由来の
readonly型を、内部で組み立てる用の書き換え可能な型に変換したいとき - オプショナルだらけの入力型から、「デフォルト値を埋めた後の必須版」の型を作りたいとき
コード例
ts
type User = {
readonly id: string;
name?: string;
};
// readonly を外す
type Mutable<T> = { -readonly [K in keyof T]: T[K] };
// => { id: string; name?: string }
// ? を外す(組み込みの Required<T> と同じ)
type Concrete<T> = { [K in keyof T]-?: T[K] };
// => { readonly id: string; name: string }
// 両方
type Writable<T> = { -readonly [K in keyof T]-?: T[K] };- 逆に
+readonly/+?(+は省略可)で付け足すこともできる。
注意点
- TypeScript 2.8 以降。
Required<T>は-?の、Readonly<T>はreadonlyの組み込み版。 -?を使うと、exactOptionalPropertyTypesが無効な環境ではundefinedも取り除かれる点に注意。- 型を変えるだけで、実行時のオブジェクトが凍結/解凍されるわけではない。