打字稿:检查类型是否为联合

Nur*_*yev 12 typescript

是否可以检查给定类型是否为联合?

type IsUnion<T> = ???
Run Code Online (Sandbox Code Playgroud)

为什么我需要这个:在我的代码中,我有唯一的情况,当一些收到的类型可以是一个联合.我用分配条件类型处理它.但是,对于查看此代码的人来说,首先使用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
Run Code Online (Sandbox Code Playgroud)

它给false了非工会,但由于某种原因它给boolean工会......我不知道为什么.我也infer从T 尝试过U,没有成功.

PS我的用例可能看起来像某人不完美/正确/好,但无论如何标题中的问题已经出现,我想知道它是否可能(我觉得它是,但我很难自己搞清楚).

Nur*_*yev 8

所以看来我自己想出了一个答案!

这是类型(感谢Titian Cernicova-Dragomir简化它!):

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

type Foo = IsUnion<'abc' | 'def'> // true
type Bar = IsUnion<'abc'> // false
Run Code Online (Sandbox Code Playgroud)

再次,UnionToIntersection of jcalz就派上用场了!

该原则基于联合A | B不延伸交叉点的事实A & B.

操场

UPD.我傻到不能将我的类型从问题发展到这个,这也很好:

type IsUnion<T, U extends T = T> =
    (T extends any ?
    (U extends T ? false : true)
        : never) extends false ? false : true
Run Code Online (Sandbox Code Playgroud)

它将联盟分配T给成员,T然后检查U哪个联盟扩展了成分T.如果是,那么它不是一个联合(但是我仍然不知道为什么它没有添加就行不通extends false ? false : true,也就是为什么前面的部分boolean为工会返回).