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]]'