我有以下功能:
export function safeParseInt<T>(value: any, invalid: T = undefined as T): number | T {
if ((value ?? "") === "") return invalid;
const parsed = parseInt(String(value));
if (isNaN(parsed)) return invalid;
return value ? parsed : 0;
}
在打字场看到这个
正如你所看到的,它有两个参数,并且返回第一个转换成整数的参数,如果不能,则返回第二个,第二个是可选的,默认为undefined。
我在键入时遇到困难。如果我使用上面的版本:
function test(value: unknown) {
const r = safeParseInt(value);
const x: number | "" = safeParseInt(value);
const y: number | "" = safeParseInt(value, "");
const z: number | "" = safeParseInt(value, undefined);
}
我预期x
和z
上会出现错误,但z
上只有一个错误。当我将鼠标悬停在r
上时,可以看到返回类型为unknown
。
默认值的某些东西扰乱了推理。我尝试过返回typeof invalid
,完全删除类型提示,使T扩展为undefined或使其扩展为unknown。似乎没有任何效果。
2条答案
按热度按时间3htmauhk1#
应使用重载。
如果
invalid
未传递给函数,则safeParseInt
的返回类型将显式设置为number | undefined
。Playground
plupiseo2#
按照当前声明函数的方式,如果没有提供
invalid
参数,它将返回unknown
结果。当然,这仍然没有通过你写的测试(下面会详细说明原因),但是这个函数的类型是正确的,如果你试图在一个不接受相同签名的函数中使用输出,编译器会警告你(也在操场链接中添加了这个)
为什么这样做...当你用变量声明一个类型时,比如
const var: <type> = ...
,typescript将使用你给出的来推断任何泛型类型。因此,当你调用没有
invalid
参数的函数时,typescript使用你的类型声明来“猜测”回退参数必须是""
类型,但是当你显式传递参数时,它使用实际的参数类型来推断泛型。当你使用参数时,这种推理不会发生,这就是为什么当我试图把它传递给函数时, typescript 会抛出一个错误。