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

TypeScript中能否获取接口对象属性的实例化特定值?

TypeScript 表格列类型的类型安全优化

问题描述

原始表格列类型定义如下:

interface Column<T> {
  key: keyof T;
  title: string;
  format?: (value: T[keyof T], record: T) => string | number;
}

其中<T>为表格记录的数据类型,列展示值通过key属性索引,format函数用于自定义格式化,接收列值(类型为T[keyof T])和记录本身。

问题在于T[keyof T]是<T>所有属性类型的联合类型。例如定义Person类型:

interface Person {
  name: string;
  weight: number;
  birthday: Date;
}

T[keyof T]等价于string | number | Date。实例化带format的列对象时,TypeScript无法确定value的具体类型,导致报错:

const column: Column<Person> = {
  key: 'birthday',
  title: "Birth Date",
  format: (value) => value.getFullYear() // 报错:无法确认value为Date类型,无getFullYear方法
};

已知添加第二个泛型参数可解决单个列的类型问题:

export interface Column<T, K extends keyof T> {
  key: K;
  title: string;
  format?: (value: T[K], record: T) => string | number;
}

此时需手动指定键名:

const column: Column<Person, 'birthday'> = {
  key: 'birthday',
  title: "Birth Date",
  format: (value) => value.getFullYear()
};

但该方案实用性差——表格列几乎都以数组形式使用,需要单一类型声明,而非为每个列指定不同泛型参数。

核心需求:无需类型断言,通过接口/辅助类型让format的value类型自动匹配key对应的具体属性类型,同时支持数组用单一类型声明。

解决方案

将Column定义为联合类型,通过映射类型遍历T的所有键,生成每个键对应的列类型:

type Column<T> = {
  [K in keyof T]: {
    key: K;
    title: string;
    format?: (value: T[K], record: T) => string | number;
  };
}[keyof T];

原理说明

  • 映射类型{ [K in keyof T]: ... }会为T的每个键K生成对应的列类型,其中format的value类型精确为T[K];
  • 最后通过[keyof T]将映射类型转换为联合类型,每个联合成员对应T的一个键的列类型。

使用示例

const columns: Column<Person>[] = [
  {
    key: 'name',
    title: '姓名',
    format: (value) => value.toUpperCase() // value自动推断为string
  },
  {
    key: 'weight',
    title: '体重',
    format: (value) => `${value}kg` // value自动推断为number
  },
  {
    key: 'birthday',
    title: '生日',
    format: (value) => value.getFullYear().toString() // value自动推断为Date
  }
];

此时数组使用单一Column<Person>[]类型声明,每个列的format函数参数类型会被TypeScript自动推断,完全满足类型安全需求,无需手动指定泛型或类型断言。

内容的提问来源于stack exchange,提问作者Chris B.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 21:33:24