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

TypeScript中基于类型而非类型映射的更简洁实现方案

解决方法

你遇到的核心问题是TypeScript类型信息在运行时不可用,所以需要找到编译时确保类型与运行时逻辑同步的方案,避免手动维护额外列表。下面是几种可行的方法:

方法一:用示例对象同步类型与运行时判断

创建一个符合Record接口的示例对象(填充默认值),通过这个对象在运行时判断列类型。新增列时TypeScript会强制你给示例对象添加对应属性,确保两者同步:

// 定义示例对象,必须完全符合Record接口
const recordExample: Record = {
  age: 0,
  ID: 0,
  item1: 0,
  item2: '',
  item3: '',
  item4: 0,
  // 新增列时,这里必须添加对应默认值,否则编译器报错
};

// 根据列名获取类型的函数
function getColumnType(column: keyof Record): 'number' | 'string' {
  return typeof recordExample[column];
}

// 业务逻辑处理
function handleColumnSelect(column: keyof Record) {
  switch(getColumnType(column)) {
    case 'string':
      functionB(column);
      break;
    case 'number':
      functionA(column);
      break;
  }
}

这个方法的优势是完全依赖TypeScript的类型检查强制同步,不需要手动维护映射列表,新增列时编译器会自动提醒你更新示例对象,从根源上避免技术债务。

方法二:用类型工具强制列列表与接口同步

如果你更倾向于维护列列表而非示例对象,可以用TypeScript的类型工具确保列表包含所有对应类型的列,新增列时编译器会报错提醒:

// 从Record接口中提取所有number类型的键
type NumberColumns = { [K in keyof Record]: Record[K] extends number ? K : never }[keyof Record];
// 提取所有string类型的键
type StringColumns = { [K in keyof Record]: Record[K] extends string ? K : never }[keyof Record];

// 定义列列表,用const断言确保类型严格
const numberColumns = ['age', 'ID', 'item1', 'item4'] as const satisfies readonly NumberColumns[];
const stringColumns = ['item2', 'item3'] as const satisfies readonly StringColumns[];

// 类型守卫函数,判断列是否为string类型
function isStringColumn(column: keyof Record): column is StringColumns {
  return (stringColumns as readonly string[]).includes(column);
}

// 业务逻辑处理
function handleColumnSelect(column: keyof Record) {
  if (isStringColumn(column)) {
    functionB(column);
  } else {
    functionA(column);
  }
}

这里用satisfies关键字确保列列表的类型与NumberColumns/StringColumns完全匹配,新增列时如果忘记更新对应列表,编译器会直接报错,强制你同步维护。

方法三:用TypeScript Transformer自动生成映射

如果项目复杂度允许,可以使用ts-transformer-keys这类编译时工具,自动从Record接口提取键和类型信息,生成运行时可用的映射:

  1. 安装依赖:npm install ts-transformer-keys --save-dev
  2. 配置TypeScript transformer(具体配置可参考工具文档)
  3. 使用工具生成映射:
import { keys } from 'ts-transformer-keys';

// 自动获取Record的所有键
const allRecordKeys = keys<Record>();

// 结合类型工具生成类型映射(需要额外的transformer支持类型提取)
const typeMapping = allRecordKeys.reduce((map, key) => {
  map[key] = typeof ({} as Record)[key] === 'number' ? 'number' : 'string';
  return map;
}, {} as { [K in keyof Record]: 'number' | 'string' });

这个方法完全自动化,不需要手动维护任何列表,但需要配置额外的编译工具,适合大型项目使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 06:44:53