[英]Typescript: Infer based on generics
为arg1
放置类型保护时,我希望自动推断arg2
,但事实并非如此。
有人知道为什么这不起作用吗? 什么是最好的选择? 非常感谢!
您可以在此处查看实际使用的类型。 只需 hover over arg2
即可查看推断的类型。
function example<T extends 'foo' | 'bar'>(
arg1: T,
arg2: T extends 'foo' ? string : number
) {
if (arg1 === 'foo') {
arg2 // should be string?
}
if (arg1 === 'bar') {
arg2 // should be number?
}
}
但是,调用 function 确实正确应用了第二种 arg 类型:
这是另一个使用基于 generics 的类型化 object 的示例:
type Test <T extends boolean> = {
multiple: T;
value: T extends true ? string : number;
};
// this doesn't work?
function test <T extends boolean>(a: Test<T>) {
if (a.multiple) {
a.value // string | number?
}else{
a.value // string | number?
}
}
// this works!
function test2 (a: Test<true> | Test<false>) {
if (a.multiple) {
a.value // is string
}else{
a.value // is number
}
}
看游乐场
我使用这两种解决方案来获得有条件的 arguments:
解决方案 1(推荐) :对 arguments 使用 object
type Args = { arg1: 'foo'; arg2: string } | { arg1: 'bar'; arg2: number };
function example(args: Args): void {
if (args.arg1 === 'foo') {
args.arg2; // It's string
}
if (args.arg1 === 'bar') {
args.arg2; // It's number
}
}
解决方案 2 :使用 arguments object
type Args = ['foo', string] | ['bar', number];
function example(...args: Args): void {
if (args[0] === 'foo') {
args[1]; // It's string
}
if (args[0] === 'bar') {
args[1]; // It's number
}
}
请考虑这个片段:
const k = 'foo' as 'foo' | 'bar'
example(k, 'abc') // compiles ok
example(k, 1) // compiles ok
arg2
与arg1
不紧密耦合。 当您使用文字字符串调用example
时: 'foo'
或'bar'
as arg1
Typescript 可以限制arg1
的类型并推断arg2
的确切类型。 但一般情况下这是不可能的。
作为一种可能的解决方法,您可以限制example
的 args,如下所示:
function example2(...args: ['foo', string] | ['bar', number]) {
if (args[0] === 'foo') {
const s = args[1] // string
}
if (args[0] === 'bar') {
const n = args[1] // number
}
}
example2('foo', '') // ok
example2('bar', 0) // ok
example('foo', 0) // error
example2(k, 'abc') // error
example2(k, 1) // error
type Test<T extends boolean>
的情况非常相似。 类型的定义并没有严格限制足够的可能值。 例如:
const v1: Test<boolean> = {
multiple: true,
value: 'a'
}
const v2: Test<boolean> = {
multiple: true,
value: 1
}
使用Test<true> | Test<false>
Test<true> | Test<false>
使用文字类型并限制一组可能的值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.