Typescript 将函数参数类型限制为union类型参数的一种情况

Typescript 将函数参数类型限制为union类型参数的一种情况,typescript,Typescript,所以我有一个元组的并集,我可以用它来声明局部变量: type KnownPair = ["dog", "paws"] | ["fish", "scales"]; const goodPair: KnownPair = ["dog", "paws"]; //@ts-expect-error you can't mix them: const badPair: KnownPai

所以我有一个元组的并集,我可以用它来声明局部变量:

type KnownPair = ["dog", "paws"] | ["fish", "scales"];

const goodPair: KnownPair = ["dog", "paws"];

//@ts-expect-error you can't mix them:
const badPair: KnownPair = ["dog", "scales"];
我想声明一个使用该类型描述多个参数的函数。我可以用spread语法完成:

function foo<T extends KnownPair>(...args: T) {
  console.log(`${args[0]} has ${args[1]}`);
}

const goodCall = foo("fish", "scales");

//@ts-expect-error you can't mix these, either:
const badCall = foo("fish", "paws");
函数foo(…参数:T){ log(`${args[0]}有${args[1]}`); } const goodCall=foo(“鱼”、“鳞”); //@ts expect error您也不能将以下内容混合使用: const badCall=foo(“鱼”、“爪子”); 但当我尝试使用常规函数参数时,它变得有趣:

function bar<T extends KnownPair>(a: T[0], b: T[1]) {
  console.log(`${a} has ${b}`);
}

const goodCall2 = bar("dog", "paws");

//@ts-expect-error Typescript rejects a bad explicit type argument:
const badCall2 = bar<["dog","scales"]>("dog", "scales");

// but it doesn't see any problems when inferring the type:
const shouldBeBad = bar("dog", "scales");
功能条(a:T[0],b:T[1]){
log(`${a}有${b}`);
}
const goodCall2=杆(“狗”、“爪子”);
//@ts expect error Typescript拒绝错误的显式类型参数:
常量badCall2=条形(“狗形”、“刻度”);
//但在推断类型时没有发现任何问题:
const shouldbebebebad=bar(“狗”、“秤”);
这就好像每个函数参数都是针对联合的每种情况单独检查的。发生什么事?是否可以以一种强制执行和执行
foo
的方式声明
bar

参考资料:

问题

function bar<T extends KnownPair>(a: T[0], b: T[1]) {

这不是问题的重点,但是:我不明白你为什么在这里使用泛型;与直接使用
KnownPair
相比,
T扩展KnownPair
是否有一些优势?如果没有,可能会删除泛型,因为它们什么都不做。如果是的话,你能编辑这个问题来说明你为什么需要它们吗?好问题,我的例子可能太简单了。我的应用程序
KnownPair
中的IIRC是另一个类型参数。这个答案是有效的(尽管我只会编写
函数栏(…[a,b]:KnownPair){}
,而不是使其通用),但OP应该注意,
bar
的实现仍然不会理解
a
b
是,如果这很重要的话。要使调用和实现都知道相关性,您几乎需要使用
args
rest参数。
function bar<T extends KnownPair>(...[a, b]: T) {
  console.log(`${a} has ${b}`);
}