🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

TypeScript

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

Q&A

解決済

1回答

424閲覧

TypeScriptの型安全について

tutti56

総合スコア86

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

TypeScript

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

1グッド

5クリップ

投稿2019/11/18 00:15

前提・実現したいこと

TypeScriptの型について質問です。
オブジェクトのキーに必ずxを持ち、yまたはzいずれかのキーのみが必要な型って可能なんでしょうか?

{ x: string, y: string }または{ x: string, z: string }のみを受け入れ、
{ x: string, y: string, z: string }はエラーとしたいです。

試したこと

Union型で作ってみましたが当然のようにx, y, zを全て持つオブジェクトに対しType Errorが出ませんでした。

該当のソースコード

TypeScript

1type Props = { [key in 'x' | 'y']: string } | { [key in 'x' | 'z']: string };

補足情報(FW/ツールのバージョンなど)

TypeScript 3.7.2

s8_chu👍を押しています

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

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

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

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

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

guest

回答1

0

ベストアンサー

こんにちは

このご質問と同様の問題に、業務であたったことがあり、そのときは、以下を参考にして切り抜けました。

  • stackoverflow: [Does Typescript support mutually exclusive types?

](https://stackoverflow.com/questions/42123407/does-typescript-support-mutually-exclusive-types) の この回答 (by Guilherme Agostinelliさん)

上記を参考にすると、ご質問にある要件を満たす型 Props は以下のように書けます。

Typescript

1type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never }; 2type XOR<T, U> = (T | U) extends object ? (Without<T, U> & U) | (Without<U, T> & T) : T | U; 3 4type PropsY = { x: string, y: string }; 5type PropsZ = { x: string, z: string }; 6 7type Props = XOR<PropsY, PropsZ>; 8 9const p1: Props = { x: 'hello', y: 'world' }; // OK 10const p2: Props = { x: 'hello', z: 'world' }; // OK 11const p3: Props = { x: 'hello', y: 'world', z: '!' }; // NG

参考になれば幸いです。

投稿2019/11/18 01:29

jun68ykt

総合スコア9058

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

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

tutti56

2019/11/18 02:46

ご回答ありがとうございます。 希望通りの動きとなりました。 Conditional Types を使うとは思ってはいたんですが、私の頭ではこれは思いつかないですね。 Without<T, U> は Mapped Types を利用して Exclude で keyof T, keyof U の共通以外を抽出した新しい型を作成。 XOR<T, U> は Without で作成された型ともう一方の型を Intersection Types で結合した型を作成って感じですかね。 間違ってたらすみません。 これを機にもっと勉強いたします。 今回は本当にありがとうございました。
jun68ykt

2019/11/18 02:56

どういたしまして。 私もWithout<T, U>とXOR<T,U>を初見の際は、ちょっと時間をかけて意味を追って、その場では(いちおう)納得した覚えがありますが、今見直すと、すぐにスラスラと解読はできなかったので、復習します。 ともあれ解決されたようで、よかったです????
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問