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

TypeScript中如何将字符串映射为匹配的模板字面量类型

解决方案

你可以通过定义通用的类型工具和转换函数实现,无需为每个属性维护对应关系,代码可复用性更高。

  1. 首先定义通用的模板字面量转换类型和映射类型
// 把原属性名转换为as开头的驼峰格式模板字面量类型
type AsKey<K extends string | number | symbol> = K extends string ? `as${Capitalize<K>}` : never;

// 你的原映射类型,基于上面的工具类型实现更清晰
type SomeType<T> = {
  [P in keyof T as AsKey<P>]: number;
};
  1. 封装通用的属性名转换函数,只需要声明一次即可适配所有类型
function getAsKey<T, K extends keyof T>(key: K): AsKey<K> {
  const strKey = key as string;
  return `as${strKey.charAt(0).toUpperCase()}${strKey.slice(1)}` as AsKey<K>;
}

这里的类型断言仅封装在工具函数内部,你在业务侧使用时不需要额外做类型断言。
3. 业务侧使用示例

interface I {
  foo: number;
  bar: number;
}

const obj: SomeType<I> = {
  asFoo: 1,
  asBar: 2,
};

// 固定字面量key的场景
const str = 'foo' as const;
const value = obj[getAsKey<I>(str)]; // TS可正确识别value类型为number,属性访问完全类型安全

// 运行时动态获取string类型key的场景,可以配合类型守卫做校验
function isKeyOf<T>(key: unknown): key is keyof T {
  return typeof key === 'string' && ['foo', 'bar'].includes(key);
  // 如果不想硬写属性列表,也可以构造一个空的T实例用in判断,或者维护一个属性数组的常量即可
}

const dynamicKey: string = 'bar'; // 模拟运行时获取的字符串
if (isKeyOf<I>(dynamicKey)) {
  const dynamicValue = obj[getAsKey<I>(dynamicKey)]; // 同样类型安全
}

原写法不生效的原因

TypeScript 不会推导运行时字符串方法的返回值为模板字面量类型,toUpperCase()、slice()这类方法的返回值类型都是通用string,拼接后的结果无法匹配到SomeType的具体字面量键类型,因此需要通过泛型函数建立输入key和输出转换后key的类型关联。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 00:39:00