我有这个打字稿代码
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
具有相同的约束。
传递的参数类型只能是number
或string
,即限制为string | number
。
答案 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仅在string
和number
之间进行选择(不要猜测任何其他扩展其并集的类型(例如您的示例中的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的后代。。在我看来,这有点..罕见。