🍧
「foo?: string」と「bar: string | undefined」の違い
type Hoge = {
foo?: string;
bar: string;
}
上記のfoo
とbar
2つのプロパティの書き方ですが、
どちらもOptionalな値で同じ意味になるかと思っていましたが、
どうやら違ったよう。勘違いしていた・・🙄
違いは下記の通り。
Objectの初期作成時に省略できるかどうかが違うよう。
省略 | undefinedの代入 | |
---|---|---|
foo?: string |
○ | ○[1] |
bar: string | undefined |
❌ | ○ |
bar: string | undefined
は省略できないので、
「プロパティ 'bar' は型 '{}' にありませんが、型 'Hoge' では必須です。」というTypeエラーが発生する。
type Hoge = {
foo?: string;
bar: string | undefined;
}
const huga: Hoge = {}
// エラー:プロパティ 'bar' は型 '{}' にありませんが、型 'Hoge' では必須です。
ReactのPropsの型定義でも同様。
foo
は省略できるが、bar
はできないのでTypeエラーが発生する。
type Hoge = {
foo?: string
bar: string | undefined
}
const Child = ({ foo, bar }: Hoge) => {
// 中略
}
export const Parent = () => {
return <Child /> // プロパティ 'bar' は型 '{}' にありませんが、型 'Hoge' では必須です。
}
-
tsconfigのexactOptionalPropertyTypesプロパティで、undefinedの代入を禁止することも可能です。 ↩︎
Discussion
(参考までに) TypeScript の
exactOptionalPropertyTypes
というオプションがtrue
になっているときに、このような違いが出ます。何も設定しないときには
false
なので、おそらくtsconfig.json
で有効になっている (あるいはこのオプションを有効にするルールを extend している)のだと思います。コメントありがとうございます!
exactOptionalPropertyTypes
オプションはfalse
ですが、本記事の違いは現れます。exactOptionalPropertyTypes
オプションは、foo?: string
で定義されたプロパティにundefined
を渡すことを許容するか否かという認識です。参考:https://typescriptbook.jp/reference/tsconfig/exactoptionalpropertytypes
ホントだ!
| undefined
なプロパティは省略不可能なのはオプション関係無かったですね...失礼しました 🙇♂
いえいえ、コメントありがたいです。
undefined
の代入の可否については、exactOptionalPropertyTypes
で変わる旨を注釈いれてみました🤭