1. ホーム
  2. typescript

[解決済み] ユニオン型からインターセクション型への変換

2022-09-01 10:39:53

質問

論理和型から論理積型に変換する方法はありますか?

type FunctionUnion = () => void | (p: string) => void
type FunctionIntersection = () => void & (p: string) => void

に変換をかけたい。 FunctionUnion に適用して FunctionIntersection

どのように解決するのですか?

論理和から論理積に変更しますか? 条件分岐型 条件付き型からの推論 がそれを可能にします。 (交差結合はできないと思いますが。すみません) これが邪道マジックです。

type UnionToIntersection<U> = 
  (U extends any ? (k: U)=>void : never) extends ((k: infer I)=>void) ? I : never

これは、ユニオンを分散させる U を分配し、すべての構成要素がcontravariantな位置にある新しい和集合に再パッケージ化します。 これにより、型は交差点として推論されるようになる I として推論することができます。

同様に、逆変数の位置にある同じ型変数の候補が複数あると、交差型が推論されることになります。


動作するかどうか見てみましょう。

まず、あなたの FunctionUnionFunctionIntersection というのは、TypeScriptは関数のreturnよりもunion/intersectionをより強く束縛しているように見えるからです。

type FunctionUnion = (() => void) | ((p: string) => void);
type FunctionIntersection = (() => void) & ((p: string) => void);

テスト中です。

type SynthesizedFunctionIntersection = UnionToIntersection<FunctionUnion>
// inspects as 
// type SynthesizedFunctionIntersection = (() => void) & ((p: string) => void)

良さそうですねぇ。

注意点としては、一般的に UnionToIntersection<> はTypeScriptが実際のユニオンだと考えていることの詳細をいくつか暴露していることに注意。 例えば boolean はどうやら内部的には true | false と表現されるようです。

type Weird = UnionToIntersection<string | number | boolean>

になる

type Weird = string & number & true & false

は、TS3.6+ではeagerlyに縮小され

type Weird = never

である値を持つことは不可能だからです。 string number true false .

お役に立てれば幸いです。 幸運を祈ります。