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

TypeScript泛型获取属性类型报错问题求助

解决TypeScript中根据对象属性键推导对应类型字段的问题

要实现根据name对应的T属性类型自动推导type字段的类型,你需要让name和type在类型层面建立绑定关系,而不是使用松散的联合类型。以下是可行的解决方案:

正确实现代码

interface Req {
  stringField: string;
  dateField: string;
  numberField: number;
}

// 单个Field类型,用泛型K绑定具体的属性键
type Field<T, K extends keyof T> = {
  name: K;
  // 根据T[K]的类型推导type的可选值
  type: T[K] extends number 
    ? 'number' 
    : T[K] extends string 
      ? 'string' | 'date' 
      : never;
};

// 生成所有合法的Field联合类型
type AllFields<T> = { [K in keyof T]: Field<T, K> }[keyof T];

// 使用联合类型数组,TypeScript会自动校验每个元素的合法性
const arr: AllFields<Req>[] = [
  { name: 'stringField', type: 'string' },
  { name: 'dateField', type: 'date' },
  { name: 'numberField', type: 'number' },
  // 以下写法会触发类型错误,符合预期
  // { name: 'stringField', type: 'number' },
  // { name: 'numberField', type: 'string' }
];

原写法问题分析

  1. Type1的语法错误:
    T.Field<T>['name']是非法语法,T是类型而非命名空间/对象,不能通过.访问内部类型,因此即使添加@ts-ignore也无法彻底消除错误。

  2. Type2的逻辑缺陷:
    Field<T>['name']本质是keyof T(所有属性键的联合),因此T[Field<T>['name']]等价于T[keyof T],即Req所有属性类型的联合(string | number)。此时(string | number) extends number的结果为false,导致type永远被推导为'string'|'date',无法匹配numberField的场景。

方案核心思路

通过引入泛型参数K,将name的具体键与type的推导逻辑绑定:每个Field<T, K>实例中,name固定为K,type则严格根据T[K]的类型生成对应可选值。AllFields<T>通过映射类型遍历所有属性键,生成所有合法的Field类型联合,确保数组中每个元素的name和type始终匹配。

内容的提问来源于stack exchange,提问作者guang y

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 00:05:25