🍧
「foo?: string」と「bar: string | undefined」の違い
type Hoge = {
foo?: string;
bar: string;
}
上記のfooとbar2つのプロパティの書き方ですが、
どちらも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で変わる旨を注釈いれてみました🤭