[TypeScript] Readonly型の知られざる?効用

公開:2020/09/21
更新:2020/09/23
2 min読了の目安(約1200字TECH技術記事

※執筆時点の TypeScriptバージョンは 4.0.2 です

2020.9.23 追記
ReadOnly に限らず、一番外側にMapped Typeを置くことで簡略化されるっぽいというのを教えていただきました。

TL; DR

https://twitter.com/wonderful_panda/status/1307841069392908290

困りごと

TypeScriptでちょっと複雑な型を書いていると、すぐに何がなんだかわからなくなる。

↓これなんかごく単純な型操作の類(MakeOptional をわざわざ2つに分けてるのはやや反則ぎみだけど、リアルワールドで型操作してるとこの程度のことはいくらでも発生するので許してほしい)だけど、

type MakeOptional<T, K extends keyof T> = Partial<Pick<T, K>> & Omit<T, K>

type X = { foo: string, bar: string, baz: string }
type Y = MakeOptional<MakeOptional<X, 'foo'>, 'bar'>

↓このポップアップ見て Y{ foo?: string, bar?: string, baz: string }だってぱっとわかります?

これなんかまだ "foo" | "baz" って表示されてるからマシな方で、場合によっては "foo" | ... 3 more ... | "baz" みたいになって本当に何も分からない。

解決策

ここで Readonly をあててみる。

type MakeOptional<T, K extends keyof T> = Partial<Pick<T, K>> & Omit<T, K>

type X = { foo: string, bar: string, baz: string }
type Y = MakeOptional<MakeOptional<X, 'foo'>, 'bar'>
type ReadonlyY = Readonly<Y> // new !

と、この通り

とても分かりやすい!

なぜそうなるのか

分かりません。詳しい人に聞いてください。
というかだれか詳しい人が教えてくれないかなと思ってこれを書きました。