gpt4 book ai didi

typescript - 将泛型参数约束为 Typescript 中的联合类型

转载 作者:行者123 更新时间:2023-12-05 09:31:10 31 4
gpt4 key购买 nike

Typescript 中有没有办法将泛型参数限制为联合类型?为了说明我的意图,下面我假设 T extends UnionType 将实现此目的:

function doSomethingWithUnion<T extends UnionType>(val: T) {}

doSomethingWithUnion<number | string>(...) // good
doSomethingWithUnion<number>(...) // should result in an error

我在另一个 SO 问题 (53953814) 中发现我们可以检查一个类型是否是联合类型:

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

type Foo = IsUnion<string | number> // true
type Bar = IsUnion<string> // false

例如,如果泛型参数不是联合类型,它允许断言函数永远不会返回:

declare function doSomethingWithUnion<T>(val: T): [T] extends [UnionToIntersection<T>] ? never: boolean;

doSomethingWithUnion<number>(2) // never
doSomethingWithUnion<string|number>(2) // => boolean

( Link to playground )

但是,我还没有找到以类似方式约束类型本身的方法。

最佳答案

Typescript 只允许您为泛型类型参数指定上限,而不是下限或任何其他约束。所以看起来应该是不可能的,一开始我以为一定是。但事实证明,通过使 T 的上限取决于 T 本身,这是可能的。

function test<T extends (IsUnion<T> extends true ? any : never)>(arg: T): T {
// ...
return arg;
}

// OK
test<string | number>('foobar');

// Error: Type 'string' does not satisfy the constraint 'never'.
test<string>('foobar');

// Error: Argument of type 'string' is not assignable to parameter of type 'never'.
test('foobar');

我能想到的一个警告是 T 可以始终是 never,即使那不是联合。这是不可避免的,因为 never 扩展了所有内容,因此它扩展了类型变量可能具有的任何上限。但是如果 Tnever 那么这个函数只能用 never 类型的参数来调用(即它永远不能被调用),所以这个在实践中应该不是问题。

如果你需要 T 的另一个上限,你可以写那个而不是 any

Playground Link

关于typescript - 将泛型参数约束为 Typescript 中的联合类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69037829/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com