Typescript extract and create Union as a subset of a Union

Har*_*rry 4 typescript

I have the following Union type;

type MyUnionType = 'foo' | 'bar' | 'baz'
Run Code Online (Sandbox Code Playgroud)

I would like to create a new Union MySubUnion as a subset;

type MySubUnion = 'foo' | 'bar'
Run Code Online (Sandbox Code Playgroud)

I would like MySubUnion to be constrained to the values of its parent MyUnionType

type MySubUnion = 'foo' | 'bas' // => Error Type String 'b...
Run Code Online (Sandbox Code Playgroud)

Tho*_*sch 13

使用Exclude<Type, Union>实用程序类型。

type MyUnionType = 'foo' | 'bar' | 'baz'

type SubType = Exclude<MyUnionType, 'baz'>

// SubType is now 'foo' | 'bar'
Run Code Online (Sandbox Code Playgroud)


jca*_*alz 8

将联合限制为成分子集就是子类型化。在TypeScript中,A extends B可以说A是的子类型B。(这有时在某些人看来是倒退的;通过从联合中删除元素,您可以使类型更具体,这是子类型。单词“ extends”可能看起来不合适,但这就是事实)。

不幸的是,您不能像使用extends接口那样使用狭窄的类型别名。您想使用以下无效语法:

// this is not valid TypeScript, do not use this:
type MySubUnion extends MyUnionType = 'foo' | 'bar'; // should work
type MySubUnion extends MyUnionType = 'foo' | 'bas'; // should fail
Run Code Online (Sandbox Code Playgroud)

但是你不能那样做。解决方法是,可以创建一个名为的新类型函数Extends<T, U>,该函数的结果为U但仅在Uextends 时才编译T,如下所示:

type Extends<T, U extends T> = U;
Run Code Online (Sandbox Code Playgroud)

然后,您可以将无效代码重写为以下有效代码:

type MySubUnion = Extends<MyUnionType, 'foo' | 'bar'>; // okay, compiles
Run Code Online (Sandbox Code Playgroud)

和这个:

type MySubUnion = Extends<MyUnionType, 'foo' | 'bas'>; // error:
// Type '"bas"' is not assignable to type 'MyUnionType'.
Run Code Online (Sandbox Code Playgroud)

有帮助吗?祝好运!