typescript 如何根据可选参数的类型确定返回类型

2exbekwf  于 2023-02-20  发布在  TypeScript
关注(0)|答案(2)|浏览(160)

我有以下功能:

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); 
}

我预期xz上会出现错误,但z上只有一个错误。当我将鼠标悬停在r上时,可以看到返回类型为unknown
默认值的某些东西扰乱了推理。我尝试过返回typeof invalid,完全删除类型提示,使T扩展为undefined或使其扩展为unknown。似乎没有任何效果。

3htmauhk

3htmauhk1#

应使用重载。

export function safeParseInt(value: any): number | undefined
export function safeParseInt<T>(value: any, invalid: T): number | T
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 parsed;
}

如果invalid未传递给函数,则safeParseInt的返回类型将显式设置为number | undefined
Playground

plupiseo

plupiseo2#

按照当前声明函数的方式,如果没有提供invalid参数,它将返回unknown结果。
当然,这仍然没有通过你写的测试(下面会详细说明原因),但是这个函数的类型是正确的,如果你试图在一个不接受相同签名的函数中使用输出,编译器会警告你(也在操场链接中添加了这个)
为什么这样做...当你用变量声明一个类型时,比如const var: <type> = ...,typescript将使用你给出的来推断任何泛型类型。
因此,当你调用没有invalid参数的函数时,typescript使用你的类型声明来“猜测”回退参数必须是""类型,但是当你显式传递参数时,它使用实际的参数类型来推断泛型。
当你使用参数时,这种推理不会发生,这就是为什么当我试图把它传递给函数时, typescript 会抛出一个错误。

相关问题