代入時のoptional?と|undefinedは意味が異なる
「(代入時の)optional?」と「(代入時の)undefined」は意味が異なる
exactOptionalPropertyTypesをtrueにしている時の話
以下は全て違う意味
code:a1.ts
type A1 = { x: string; hoge: string | undefined }
code:a2.ts
type A2 = { x: string; hoge?: string }
code:a3.ts
type A3 = { x: string; hoge?: string | undefined }
上の3つに代入できる値を列挙するとわかりやすい
A1に代入できるもの
code:ts
const a11: A1 = { x: 'hoge', hoge: 'hoge' };
const a12: A1 = { x: 'hoge', hoge: undefined };
A2に代入できるもの
code:ts
const a21: A2 = { x: 'hoge', hoge: 'hoge' };
const a22: A2 = { x: 'hoge' };
A3に代入できるもの
code:ts
const a31: A3 = { x: 'hoge', hoge: 'hoge' };
const a32: A3 = { x: 'hoge', hoge: undefined};
const a33: A3 = { x: 'hoge' };
ちなみにexactOptionalPropertyTypesがfalseの場合は、
上記のA2とA3が同一視される
アクセスするときは同じ
いずれもstring | undefinedになる
code:ts
const a: A = ..
a.hoge // string | undefined
どこで問題が起きるか?
Object.keysなど、objectの具体的な形にアクセスするときに差が出る
例えば、
Object.keys(A1のもの)の時は、常に['x','hoge']が返るが、
Object.keys(A2のもの)の時は、
['x']の時と、
['x', 'hoge']の時とがありうる
ref objectの具体的な形にアクセスすると矛盾が生じる
https://oita.oika.me/2021/12/01/timeleap-typescript#:~:text=プロパティをnullableにする目的でオプショナルにしない