Typescript:タイプが共用体であるかどうかを確認します

15
Nurbol Alpysbayev 2018-12-28 04:52.

特定のタイプがユニオンであるかどうかを確認することはできますか?

type IsUnion<T> = ???

これが必要な理由:私のコードでは、受け取った型の一部が共用体になる可能性があるのは私だけです。私はそれを分配条件型で扱います。ただし、このコードを見ると、そもそもなぜDCTが使用されているのかがわかりません。だから私はそれを次のように明示的にしたいと思います:IsUnion<T> extends true ? T extends Foo ...

で何度か試しましたが、UnionToIntersection結果はありませんでした。私もこれを思いついた:

type IsUnion<T, U extends T = T> =
    T extends any ?
    (U extends T ? false : true)
    : never

それはfalse非組合に与えます、しかし何らかの理由でそれはboolean組合に与えます...そして私は理由がわかりません。私もinferTからUを試みましたが、成功しませんでした。

PS私のユースケースは、完璧/正しく/良くないように見えるかもしれませんが、とにかくタイトルの質問が発生し、それが可能かどうか疑問に思います(そうだと思いますが、自分で理解するのに苦労しています)。

2 answers

12
Nurbol Alpysbayev 2018-12-28 15:08.

だから私は自分で答えを思いついたようです!

タイプは次のとおりです(単純化してくれたTitian Cernicova-Dragomirに感謝します!):

type IsUnion<T> = [T] extends [UnionToIntersection<T>] ? false : true

type Foo = IsUnion<'abc' | 'def'> // true
type Bar = IsUnion<'abc'> // false

そしてまた https://stackoverflow.com/a/50375286/9259778 jcalzのが重宝しました!

原則は、ユニオンA | Bが交差点を拡張しないという事実に基づいていA & Bます。

http://www.typescriptlang.org/play/index.html#src=type%20UnionToIntersection%3CU%3E%20%3D%20(U%20extends%20any%20%3F%20(k%3A%20U)%20%3D%3E%20void%20%3A%20never)%20extends%20((k%3A%20infer%20I)%20%3D%3E%20void)%20%3F%20I%20%3A%20never%0A%0Atype%20IsUnion%3CT%3E%20%3D%20%5BT%5D%20extends%20%5BUnionToIntersection%3CT%3E%5D%20%3F%20false%20%3A%20true%0A%0Atype%20Foo%20%3D%20IsUnion%3C%27sdf%27%20%7C%20%27zcx%27%3E%0Atype%20Bar%20%3D%20IsUnion%3C%27sdf%27%3E

UPD。私は自分のタイプを質問からこの質問に発展させないほど愚かでしたが、これもうまく機能します:

type IsUnion<T, U extends T = T> =
    (T extends any ?
    (U extends T ? false : true)
        : never) extends false ? false : true

ユニオンTを構成要素に配布しT、次に、Uどちらのユニオンが構成要素を拡張するかをチェックしますT。はいの場合、それはユニオンではありません(ただしextends false ? false : true、追加しないと機能しない理由、つまり前の部分がbooleanユニオンに戻る理由はまだわかりません)。

2
Keith Layne 2020-01-11 02:17.

注:この回答は、誰かが明示的に使用したくない場合のものUnionToIntersectionです。そのバージョンはシンプルで理解しやすいので、不安がない場合はそれを使用U2Iしてください。

私はこれをもう一度見て、@ Gerrit0の助けを借りてこれを思いついた:

// Note: Don't pass U explicitly or this will break.  If you want, add a helper
// type to avoid that.
type IsUnion<T, U extends T = T> = 
  T extends unknown ? [U] extends [T] ? false : true : false;

type Test = IsUnion<1 | 2> // true
type Test2 = IsUnion<1> // false
type Test3 = IsUnion<never> // false

さらに簡略化できるようで、とても満足しています。ここでの秘訣は配布ですが、比較できるようにするためではありTませんU。したがって、のtype X = 1 | 2場合、[1 | 2] extends [1]どちらがfalseであるかを確認することになり、このタイプはtrue全体的になります。私T = neverたちも決心した場合false(Gerritに感謝)。

タイプが共用体でない場合、TUは同一であるため、このタイプはに解決されfalseます。

警告

これが機能しない場合があります。別のメンバーに割り当て可能なメンバーとのユニオンbooleanは、の配布により解決されTます。おそらくこれの最も単純な例{}は、ほとんどすべて(プリミティブでさえ)がそれに割り当て可能であるため、がユニオンにある場合です。また、一方が他方のサブタイプである2つのオブジェクトタイプを含むユニオンでも表示されます{ x: 1 } | { x: 1, y: 2 }

回避策

  1. 3番目のextends句を使用します(Nurbolの回答のように)
(...) extends false ? false : true;
  1. never誤ったケースとして使用します。
T extends unknown ? [U] extends [T] ? never : true : never;
  1. extendsコールサイトでを反転します。
true extends IsUnion<T> ? Foo : Bar;
  1. 呼び出しサイトでこれを使用するには、おそらく条件型が必要なので、次のようにラップします。
type IfUnion<T, Yes, No> = true extends IsUnion<T> ? Yes : No;

ニーズに応じて、このタイプで実行できるバリエーションは他にもたくさんあります。1つのアイデアはunknown、肯定的なケースに使用することです。その後、あなたはすることができますT & IsUnion<T>。またはT、それを使用して呼び出すことAssertUnionもできます。これにより、タイプ全体がneverユニオンでない場合になります。空が限界です。

バグを見つけて回避策についてフィードバックを提供してくれたgitterの@ Gerrit0と@AnyhowStepに感謝します。

Related questions

MORE COOL STUFF

ケイト・ブランシェットは3日間一緒に夫と一緒に寝て、25年経ってもまだ夫と結婚しています

ケイト・ブランシェットは3日間一緒に夫と一緒に寝て、25年経ってもまだ夫と結婚しています

ケイト・ブランシェットは、夫に会ったとき、典型的な交際のアドバイスに逆らいました。

マイケルシーンが非営利の俳優である理由

マイケルシーンが非営利の俳優である理由

マイケルシーンは非営利の俳優ですが、それは正確にはどういう意味ですか?

ホールマークスターのコリンエッグレスフィールドがRomaDramaLiveでスリル満点のファンと出会う![エクスクルーシブ]

ホールマークスターのコリンエッグレスフィールドがRomaDramaLiveでスリル満点のファンと出会う![エクスクルーシブ]

特徴的なスターのコリン・エッグレスフィールドは、RomaDrama Liveでのスリル満点のファンとの出会いについて料理しました!加えて、大会での彼のINSPIREプログラム。

「たどりつけば」をオンラインでストリーミングできない理由

「たどりつけば」をオンラインでストリーミングできない理由

ノーザンエクスポージャーが90年代の最も人気のある番組の1つになった理由を確認するには、Blu-rayまたはDVDプレーヤーをほこりで払う必要があります。

バイオニック読書はあなたをより速く読むことができますか?

バイオニック読書はあなたをより速く読むことができますか?

BionicReadingアプリの人気が爆発的に高まっています。しかし、それは本当にあなたを速読術にすることができますか?

ドミニカのボイリング湖:アクセスは簡単ではありませんが、ハイキングする価値があります

ドミニカのボイリング湖:アクセスは簡単ではありませんが、ハイキングする価値があります

ドミニカのボイリング湖は、世界で2番目に大きいボイリング湖です。そこにたどり着くまでのトレッキングは大変で長いですが、努力する価値は十分にあります。

私たちの水をきれいに保つのを助けるためにあなたの髪を寄付してください

私たちの水をきれいに保つのを助けるためにあなたの髪を寄付してください

サロンからのヘアトリミングや個人的な寄付は、油流出を吸収して環境を保護するのに役立つマットとして再利用できます。

ホワイトハウスの最も記憶に残る結婚式を見てください

ホワイトハウスの最も記憶に残る結婚式を見てください

過去200年以上の間にホワイトハウスで結婚したのはほんの数人です。彼らは誰でしたか、そしてそこで結婚式を獲得するために何が必要ですか?

控訴裁判所によって取り下げられたメタン規制の施行を遅らせるEPAの試み

控訴裁判所によって取り下げられたメタン規制の施行を遅らせるEPAの試み

ゲッティ経由の画像。スコット・プルイットは環境保護庁の長であり、二酸化炭素とメタンガスとの愛情のこもった関係を持っていますが、彼は地球温暖化を信じることに冷たい肩を与えています。

メッセージングアプリの「誰かが入力している」バブルが実際に意味するもの

メッセージングアプリの「誰かが入力している」バブルが実際に意味するもの

一連の点滅する省略記号であろうと、「誰かが入力している」という明示的な通知であろうと、入力インジケーターと呼ばれるメッセージング機能は、多くの人にとって便利なツールであり、不安の原因でもあります。しかし、それがどのように機能するかについてもっと知ることは、少なくとも私たちにストレスを引き起こす推測ゲームを制限することができます。

マット・ラウアーは、離婚の和解で数百万ドルと馬の農場を失うことに「激怒」したと伝えられています

マット・ラウアーは、離婚の和解で数百万ドルと馬の農場を失うことに「激怒」したと伝えられています

マット・ラウアーと彼の妻のアネット・ロークは結婚間近であり、離婚手続きが激化していると伝えられています。ある情報筋は、ラウアーが「和解で約5,000万ドルをフォークする予定」であり、「マットは激怒している」と語った。彼は本質的に彼の純資産の半分をアネットに手渡している。

まあ、これは厄介です:レイプ告発者はケレンウィンズロージュニアの弁護士を彼女の攻撃者として特定します

まあ、これは厄介です:レイプ告発者はケレンウィンズロージュニアの弁護士を彼女の攻撃者として特定します

2018年6月15日金曜日、カリフォルニア州ビスタでの罪状認否の際、元NFLフットボール選手のケレンウィンズロージュニア(中央)が弁護士のブライアンワトキンス(左)とハーベイスタインバーグの後ろに立っています。

Zendaya Wishes Boyfriend Tom Holland Happy Birthday with Cuddly Photo: He 'Makes Me the Happiest'

Zendaya Wishes Boyfriend Tom Holland Happy Birthday with Cuddly Photo: He 'Makes Me the Happiest'

Zendaya shared a sweet photo in honor of boyfriend Tom Holland's 26th birthday Wednesday

小さな女性:脳卒中を患った後に病院から解放されたアトランタのジューシーな赤ちゃん:「まだ癒し」

小さな女性:脳卒中を患った後に病院から解放されたアトランタのジューシーな赤ちゃん:「まだ癒し」

シーレン「Ms.JuicyBaby」ピアソンは、先月脳卒中で入院した後、「もう一度たくさんのことをする方法を学ばなければならない」ため、言語療法を受けていることを明らかにしました。

エマストーンは彼女のクリフサイドマリブビーチハウスを420万ドルでリストアップしています—中を見てください!

エマストーンは彼女のクリフサイドマリブビーチハウスを420万ドルでリストアップしています—中を見てください!

オスカー受賞者の世紀半ばの家には、3つのベッドルーム、2つのバス、オーシャンフロントの景色があります。

ジーニー・メイ・ジェンキンスは、母乳育児の経験の中で、彼女は「本当に、本当に落ち込んでいる」と言います

ジーニー・メイ・ジェンキンスは、母乳育児の経験の中で、彼女は「本当に、本当に落ち込んでいる」と言います

ジーニー・メイ・ジェンキンスは、生後4か月の娘、モナコに母乳育児をしていると語った。

投資ノート:Bioscout AU$300万シード

投資ノート:Bioscout AU$300万シード

Bioscoutは、農家を運転席に置くという使命を負っています。Artesian(GrainInnovate)やUniseedと並んで、最新のシードラウンドでチームを支援できることをうれしく思います。問題真菌症による重大な作物の損失は、農民にとって試練であることが証明されています。

リトルマーケットリサーチ1| 2022年のクイックグリンプス遠隔医療市場

リトルマーケットリサーチ1| 2022年のクイックグリンプス遠隔医療市場

遠隔医療は、パンデミック後の時代では新しいものではなく、時代遅れの分野でもありません。しかし、業界を詳しく見ると、需要と供給の強力な持続可能性と、米国で絶え間ない革命となる強力な潜在的成長曲線を示しています。

スタートアップ資金調達環境:タイのスタートアップエコシステムの次は何ですか?

スタートアップ資金調達環境:タイのスタートアップエコシステムの次は何ですか?

2021年は、世界的なベンチャーキャピタル(VC)の資金調達にとって記録的な年でした。DealStreetAsiaによると、東南アジアも例外ではなく、この地域では年間で記録的な25の新しいユニコーンが採掘されました。

ムーアの法則を超えて

ムーアの法則を超えて

計算に対する私たちの欲求とムーアの法則が提供できるものとの間には、指数関数的に増大するギャップがあります。私たちの文明は計算に基づいています—建築と想像力の現在の限界を超える技術を見つけなければなりません。

Language