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

TypeScript中如何让ICol的formatValue参数类型与accessor关联?

解决TypeScript泛型接口中accessor与formatValue参数类型关联的问题

原接口设计里,当指定accessor为具体字段时,formatValue的参数类型无法和该字段的类型绑定,而是变成所有可能属性类型的联合。问题根源在于泛型参数K被设定为keyof T的联合类型,导致T[K]自动展开为所有属性类型的集合。

解决方案:用映射类型生成强关联的联合类型

重新定义ICol为联合类型,每个成员对应T的一个具体键,让accessor和formatValue的参数类型强绑定:

import type { JSX } from 'react'; // 若用到JSX.Element需导入该类型

type ICol<T extends Record<string, any>> = 
  // 覆盖所有指定accessor的场景:每个键对应独立的类型成员
  | { [K in keyof T]: {
      accessor: K;
      formatValue?: (value: T[K]) => JSX.Element | string | number;
    } }[keyof T]
  // 保留不指定accessor的合法场景
  | {
      accessor?: never;
      formatValue?: never;
    };

代码验证

用测试类型验证类型提示是否符合预期:

// 测试用数据类型
type TestData = {
  a: number;
  b: string;
  c: Date;
};

// 指定accessor为'a'时,formatValue的value自动提示为number类型
const colA: ICol<TestData> = {
  accessor: 'a',
  formatValue: (value) => {
    return value.toFixed(2); // 此处value类型为number,可直接调用number专属方法
  }
};

// 指定accessor为'b'时,value自动提示为string类型
const colB: ICol<TestData> = {
  accessor: 'b',
  formatValue: (value) => {
    return value.toUpperCase(); // 此处value类型为string,可直接调用string专属方法
  }
};

// 不指定accessor的合法示例
const colEmpty: ICol<TestData> = {};

原理说明

通过{ [K in keyof T]: ... }[keyof T]的映射类型,我们为T的每个键生成一个独立的对象类型,再将这些类型合并为联合类型。当TypeScript推断到具体的accessor值时,会自动缩小联合类型到对应的成员,从而让formatValue的参数类型精准匹配accessor对应的字段类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 07:45:03