Typescript 为数组添加类型,就像泛型对象中的属性值一样
假设您有一个函数:Typescript 为数组添加类型,就像泛型对象中的属性值一样,typescript,Typescript,假设您有一个函数: 获取具有多个属性和属性名称的对象 检查属性是否包含数组 如果是这样,它会对其进行处理(即打印它包含的值) 这里我们有一个例子: 函数printIfKeyIsAnArray(值,字段){ if(Array.isArray(值[字段]){ 值[field].map(x=>console.log(x)); } 返回null; } 以下类型似乎工作正常,arrayvalue仅从T的属性中提取类似于数组的类型: 类型StringKey=keyof T 类型ArrayValues=T[
函数printIfKeyIsAnArray(值,字段){
if(Array.isArray(值[字段]){
值[field].map(x=>console.log(x));
}
返回null;
}
以下类型似乎工作正常,arrayvalue
仅从T
的属性中提取类似于数组的类型:
类型StringKey=keyof T
类型ArrayValues=T[
{
[K in keyof T]:T[K]扩展任何[]?K:从不
}[keyof T]
]
X型={
傅:字符串,
条:字符串[],
qux:编号[],
}
//常量数组值:string[]| number[]->Hurray!
常量arrayValues:arrayValues=['a'];
现在,如果我尝试在上面的函数中使用这些类型,Typescript将引发一个错误:
函数printIfKeyIsAnArray(值:T,字段:keyof T){
if(Array.isArray(值[字段]){
常量arrayValue=作为arrayValue的值[字段];
arrayValue.map(x=>console.log(x));
}
返回null;
}
为什么??我遗漏了什么/做错了什么?问题是
Array.isArray
没有缩小值[字段]
的类型,因为后者不是一个可以缩小的表达式。如果您首先将值[field]
分配给变量,那么它将进行所有类型检查,而无需执行任何特殊操作:
函数printIfKeyIsAnArray(值:T,字段:keyof T){
常数p=值[字段];
//推断类型p:T[keyof T]
if(数组isArray(p)){
//将类型缩小为p:T[keyof T]和any[]
p、 map(x=>console.log(x));
}
返回null;
}
如果您只是想知道如何修复arrayvalue
泛型类型,请将T[…]
移动到K
而不是整个类型:
键入数组值=
{
[K in keyof T]:T[K]扩展任何[]?T[K]:从不
}[keyof T]
这并不能回答您的问题,但您在这里所做的是逻辑上的forEach
,而不是map
,因为您不想构建新阵列;您可以编写.forEach(console.log)
,而无需编写lambda。谢谢!你能解释一下当你移动T[…]
应用于K
而不是整个事物时会发生什么变化吗?检查类型它们看起来完全一样,但是你的代码和我的代码工作正常没有:D任何文档?我最好的猜测是Typescript能够推断T[K]扩展了任何[]?T[K]:never
是any[]
的一个子类型,因为有一个关于条件类型的简单规则,而另一个版本太复杂了,没有一个特定的类型推断规则与之关联。即使是更简单的type Test=T[T[K]扩展了any[]?K:never]
也不会被推断为any[]
的子类型。
Property 'map' does not exist on type 'T[{ [K in keyof T]: T[K] extends any[] ? K : never; }[keyof T]]'