5.0引入了const类型参数。是否可以通过这样的类型参数捕获varargs?
下面的函数尝试这样做:
function insertIf<const V extends any[]>(condition: boolean, ...value: V): V | readonly [] {
if (condition) {
return value;
} else {
return [];
}
}
不幸的是,返回类型总是派生为any[] | readonly []
,而不管给函数的实际参数是什么。
示例调用为insertIf(true, { s: 'a' }, { s: '?'})
1条答案
按热度按时间yzuktlbb1#
您应该将
V
上的约束从any[]
更改为readonly
数组类型,如readonly any[]
:在microsoft/TypeScript#51865的描述中,实现
const
类型参数的pull请求说:当
const
类型参数被约束为数组类型时,该数组类型应包含readonly
修饰符;否则,类型参数的推断将不能满足约束。对于你的原始版本:
编译器实际上希望在这里将
V
推断为readonly [{ readonly s: "a"; }, { readonly s: "?"; }]
,就像您使用了const
Assert一样。但该类型 * 不可 * 分配给any[]
;与普通读写阵列相比,只读阵列具有较少的已知方法。因此,推断步骤失败,编译器福尔斯到
any[]
的约束,该约束通过了类型检查,您的代码看起来像是无声的失败。这绝对是一个混乱的点,之前已经被报告为一个bug,参见microsoft/TypeScript#51931,如果编译器以某种方式警告你
const
修饰符不会很好地工作,但至少现在这是按预期工作的,解决方案是添加readonly
修饰符。Playground链接到代码