推断类型为“ 1”而不是数字

时间:2020-09-28 19:22:10

标签: typescript

我有这个打字稿代码

type X = (<T extends number | string>(a: T) => (b: T) => T)

const f: X = (a: any) => (b: any) => a + b

f(1)(2)

显示错误

Argument of type '2' is not assignable to parameter of type '1'.

第一个参数中的推断类型为'1',但我希望它是number,并且对泛型string | number具有相同的约束。

传递的参数类型只能是numberstring,即限制为string | number

Playground

2 个答案:

答案 0 :(得分:3)

这对您的情况有用吗?

type XGen<T extends string | number> = (a: T) => (b: T) => T;
type X = XGen<string> & XGen<number>;
const f: X = (a: any) => (b: any) => a + b;

f(1)(2);
f(1)('2'); // error
f('1')('2');
f([])([]); // error

目标是指示TypeScript仅在stringnumber之间进行选择(不要猜测任何其他扩展其并集的类型(例如您的示例中的1))。我们通过创建基本的通用帮助程序类型XGen并创建XGen<string>XGen<number>的交集类型(因此迫使打字稿只能在这两种类型之间进行选择)来实现这一点。

答案 1 :(得分:0)

为什么<T extends number | string>而不是<T=number|string>

我刚刚尝试过

type X = (<T = number | string>(a: T) => (b: T) => T)

const f: X = (a: any) => (b: any) => a + b

console.log( f(1)(2) );
console.log( f("1")("2") );

结果:

[LOG]: 3 
[LOG]: "12" 

在您给我们的同一个操场上,效果很好。

自从我上次编写任何TS代码以来已经有一段时间了,但是我认为当您使用extends约束时,您在暗示T将是某些派生类型,并且是唯一可与f(1)匹配的类型。是某种“文字类型”。我的意思是,1已从number“升级”为文字类型“ 1”(与文字字符串作为类型的机制相同,只是数字文字而不是字符串文字)。

我敢打赌,您并不是说X类型是Number的后代还是String的后代。。在我看来,这有点..罕见。