You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript自动列类型定义问题:数组键回调参数为any类型

TypeScript数组键列类型定义问题修复

我写了一段自动为列定义类型的TS代码,无需手动指定类型,但处理数组类型的键时出现问题:高亮render键时显示的类型正确,但实际回调函数中的value参数类型却为any。相关代码如下:

type Payload = {
  name: string;
  items: string[];
};

type Render<P> = (value: P) => any;

type Col<
  T extends object,
  K = keyof T | Array<keyof T>
> = K extends Array<keyof T>
  ? {
      key: K;
      render: Render<{ [key in K[number]]: T[key] }>
    }
  : K extends keyof T ? {
      key: K;
      render: Render<T[K]>
    } : never


const cols: Col<Payload>[] = [
  { 
    key: 'name', 
    render: (name) => name 
  },
  { 
    key: ['name', 'items'],
    render: (obj) => `${obj.name} - ${obj.items.length}`
  },
];

问题原因

原Col类型的默认泛型参数K = keyof T | Array<keyof T>是联合类型,TypeScript无法对数组类型的K进行正确的分布式条件类型推导。当处理数组键分支时,K没有被窄化到具体的数组元素集合,导致Render的泛型参数无法正确推断,最终回调参数类型退化为any。

修复方案

将Col拆分为单个键和数组键的具体类型,再合并为联合类型,让TypeScript能针对每个分支单独做类型检查:

type Payload = {
  name: string;
  items: string[];
};

type Render<P> = (value: P) => any;

// 单个键对应的列类型
type SingleCol<T, K extends keyof T> = {
  key: K;
  render: Render<T[K]>;
};

// 数组键对应的列类型
type MultiCol<T, K extends Array<keyof T>> = {
  key: K;
  render: Render<{ [Key in K[number]]: T[Key] }>;
};

// 合并所有可能的列类型
type Col<T> = 
  | SingleCol<T, keyof T> 
  | MultiCol<T, Array<keyof T>>;

const cols: Col<Payload>[] = [
  { 
    key: 'name', 
    render: (name) => name // name类型自动推断为string
  },
  { 
    key: ['name', 'items'],
    render: (obj) => `${obj.name} - ${obj.items.length}` // obj类型自动推断为{name: string; items: string[]}
  },
];

修复说明

  • 拆分类型后,TypeScript会对联合类型的每个成员单独进行类型匹配
  • 定义cols时,每个列对象会被精准匹配到SingleCol或MultiCol分支,回调参数的类型就能被正确推断出来

内容的提问来源于stack exchange,提问作者Said Benmoumen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 07:15:19