gpt4 book ai didi

typescript - 使用条件返回类型实现泛型函数

转载 作者:行者123 更新时间:2023-12-03 16:32:53 24 4
gpt4 key购买 nike

我正在尝试一个非常基本的(人为的)条件类型函数并遇到意外错误:

function test<
T
>(
maybeNumber: T
): T extends number ? number : string {
if (typeof maybeNumber === 'number') {
return maybeNumber // Type 'T & number' is not assignable to type 'T extends number ? number : string'.
}

return 'Not a number' // Type '"Not a number"' is not assignable to type 'T extends number ? number : string'.
}

我认为这是条件类型的非常简单的用法,所以不确定发生了什么。有任何想法吗?

澄清一下,我并不是真的想实现这个特定的功能。我只是在试验条件类型,想更好地理解为什么这实际上不起作用。

最佳答案

潜在的问题是 TypeScript 的编译器没有通过控制流分析来缩小泛型类型变量的类型。当您查看 (typeof maybeNumber === "number") ,编译器可以缩小值maybeNumbernumber ,但它不会缩小类型参数 Tnumber .因此它无法验证分配 number 是否安全。返回类型的值 T extends number ? number : string .编译器将不得不执行一些它目前不做的分析,例如“好吧,如果 typeof maybeNumber === "number" ,并且我们单独从 T 的类型推断 maybeNumber,那么在这个块中我们可以将 T 缩小到number ,因此我们应该返回一个类型为 number extends number ? number : string 的值,也就是 number "。但这不会发生。

对于具有条件返回类型的泛型函数,这是一个相当大的痛点。关于此的规范的开放 GitHub 问题可能是 microsoft/TypeScript#33912 ,但还有很多其他 GitHub 问题,这是主要问题。

所以这就是“为什么这行不通”的答案?

如果您对重构以使其工作不感兴趣,则可以忽略其余部分,但知道在这种情况下该做什么而不是等待语言更改可能仍然具有指导意义。

此处维护您的调用签名的最直接的解决方法是使您的函数成为单个签名 overload其中实现签名不是通用的。这实质上放松了实现内部的类型安全保证:

type MyConditional<T> = T extends number ? number : string;
type Unknown = string | number | boolean | {} | null | undefined;

function test<T>(maybeNumber: T): MyConditional<T>;
function test(maybeNumber: Unknown): MyConditional<Unknown> {
if (typeof maybeNumber === 'number') {
const ret: MyConditional<typeof maybeNumber> = maybeNumber;
return ret;
}
const ret: MyConditional<typeof maybeNumber> = "Not a number";
return ret;
}

在这里,我尽可能地尝试通过使用临时 ret 来保证类型安全。变量注释为 MyConditional<typeof maybeNumber>它使用控制流分析缩小类型 maybeNumber .如果您切换支票,这至少会提示(将 === 转为 !== 进行验证)。但通常我只是做一些像这样更简单的事情,让筹码掉到他们可能的地方:
function test2<T>(maybeNumber: T): MyConditional<T>;
function test2(maybeNumber: any): string | number {
if (typeof maybeNumber === 'number') {
return maybeNumber;
}
return "Not a number";
}

好的,希望有帮助;祝你好运!

Playground link to code

关于typescript - 使用条件返回类型实现泛型函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59904247/

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