質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

Q&A

解決済

1回答

1865閲覧

[TypeScript]複数の型を組み合わせて定義した型で、Property 'xxxx' does not exist on typeが発生する

sabx

総合スコア200

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

0グッド

0クリップ

投稿2021/10/21 10:46

聞きたいこと

下のような複数のtypeを組み合わせて Sample1and2 というtypeを定義しています。

type Sample = { id: string, name: string } type Sample2 = { id: string, gender: string } export type Sample1and2 = Sample | Sample2

この Sample1and2 を使用して、下のような関数をし定義しているのですが、引数の sample から、 gendername を引き出そうとしても型エラーになってしまいます。

const sampleFunc = ({ sample }: { sample: Sample1and2 }) => { const { gender } = sample; // ← Property 'gender' does not exist on type 'Sample1and2' const { name } = sample; // ← Property 'gender' does not exist on type 'Sample1and2' }

当然、Sample1 または Sample2 にしか存在していないプロパティ(gender or name)を使用しようとしているため、型エラーになるのはわかるのですが、

下のコードのように、型として保証ができる場合でも型エラーになってしまっていて困っています。

const sampleFunc = ({ sample }: { sample: Sample1and2 }) => { : const samplesTypeIsSample2 = true; // 実際のコードでは単純なtrue/falseの代入ではありません if (samplesTypeIsSample2) { const { gender } = sample; // ← Property 'gender' does not exist on type 'Sample1and2' } }

こういった場合にどのような実装をすればいいのでしょうか。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

判別可能なUnion型とユーザ定義のType Guardを組み合わせましょう。
型チェックやインテリセンスも効くようになり便利です。

判別可能なUnion型 - TypeScript Deep Dive 日本語版

typescript

1interface Sample1 { 2 kind: 'Sample1'; // これで判別する 3 id: string; 4 name: string; 5} 6 7interface Sample2 { 8 kind: 'Sample2'; // これで判別する 9 id: string; 10 gender: string; 11} 12 13type Sample1and2 = Sample1 | Sample2 14 15// ユーザ定義のType Guard 16function isSample1(x: Sample1and2): x is Sample1 { 17 return x.kind === 'Sample1' 18} 19 20// ユーザ定義のType Guard 21function isSample2(x: Sample1and2): x is Sample2 { 22 return x.kind === 'Sample2' 23} 24 25const sampleFunc = ({ 26 sample 27}: { 28 sample: Sample1and2 29}) => { 30 if (isSample1(sample)) { 31 console.log(sample.id, sample.name); 32 } else { 33 console.log(sample.id, sample.gender); 34 } 35 36 /* switch-caseでもOK */ 37 switch (sample.kind) { 38 case 'Sample1': 39 console.log(sample.id, sample.name); 40 break; 41 case 'Sample2': 42 console.log(sample.id, sample.gender); 43 break; 44 default: 45 // これを書いておくとSample1and2に型を足したときにここでエラーが出るようになり、 46 // caseを増やすのを忘れにくくなります。 47 const _exhaustiveCheck: never = sample; 48 } 49}

別解としてasでキャストすることもできますが、おすすめしません。

以上、ご参考になれば幸いです。

投稿2021/10/21 11:38

fj68

総合スコア752

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問