网站搜索

TypeScript 如何缩小泛型?


我写了以下代码,但返回值出现了错误

function test_fn<T> (arg: T): T extends string | number ? boolean : number
{
    if(typeof arg === "string" || typeof arg === "number")
    {
        return true
    }
    return 1
}

错误信息是:TS2322:类型 'true' 不能赋值给类型 'T extends string | number ? boolean : number'。

我觉得我的写法应该正确推断类型,但它没有做到。我该怎么办才能消除这个类型错误?

答案#1

这里有一个替代解决方案,它同样可以解决问题,并且具有额外的特点,即如果输入是字符串或数字,它也能正确地确定返回类型始终是true。

function test_fn(arg: string|number): true; 
function test_fn(arg: unknown): number; 
function test_fn(arg: string|number|unknown): true | number {

  if(typeof arg === "string" || typeof arg === "number") {
    return true;
  }
  return 1;
}


const foo = test_fn(5); // inferred as true
const bar = test_fn('hi'); // inferred as true
const zim = test_fn(true); // inferred as number

答案#2

请检查下面的代码片段,它可以解决上述问题。

type TestFnReturnType = boolean | number

function test_fn<T> (arg: T): TestFnReturnType 
{
    if(typeof arg === "string" || typeof arg === "number")
    {
        return true
    }
    return 1
}

我的实现简单地忽略了 T 的类型是否是数字。如果需要的话,你也许可以把数字转换成字符串并使用它。