如何为键名动态的对象设置TypeScript类型?
TypeScript 动态键货币对象类型定义方案
你最初写的字符串索引签名思路是正确的,只需要补全语法即可满足基础的动态键+值结构约束需求,也可以根据使用场景选择更严谨的带自动提示的写法。
基础可用版本
这个版本完全匹配你预期的效果,支持任意动态货币代码作为键,同时强制约束每个键对应值的结构:
import type { ReactNode } from 'react'; // 先抽离单个货币的属性结构,方便后续复用 interface CurrencyInfo { country: string; symbol: string; icon: ReactNode; } export interface CurrencyTypes { // 动态字符串索引签名:所有字符串类型的键,对应值必须符合CurrencyInfo结构 [currencyCode: string]: CurrencyInfo; }
这个写法的效果:
- 支持
usd、cad、cny等任意字符串作为货币键名,不需要提前枚举 - 定义货币对象时,如果某个键对应的值缺少属性、或者属性类型不匹配,TS会直接抛出类型错误
- 访问货币对象的任意属性时,TS能正确推导
country/symbol/icon的类型,不会出现隐式any
进阶严谨版本(推荐)
如果你的TS版本在4.9及以上,推荐结合satisfies运算符使用,既能保留结构约束,还能自动获得已定义货币键的自动补全,不需要手动维护键名联合类型:
import type { ReactNode } from 'react'; // 单个货币项的结构约束 type CurrencyItem = { country: string; symbol: string; icon: ReactNode; }; // 定义实际货币对象时用satisfies做校验,不会丢失具体的键名信息 const CurrencyType = { usd: { country: 'United States', symbol: '$USD', icon: <USD /> }, cad: { country: 'Canada', symbol: '$CAD', icon: <CAD /> }, } satisfies Record<string, CurrencyItem>; // 从实际对象自动推导类型,不需要手动写接口 export type CurrencyTypes = typeof CurrencyType; // 还可以直接提取合法的货币代码联合类型,后续做参数校验很方便 export type CurrencyCode = keyof CurrencyTypes; // 推导结果为 'usd' | 'cad'
这个写法额外的优势:
- 新增货币类型时只需要往
CurrencyType对象里加配置即可,TS会自动同步类型,不需要手动修改接口定义 - 编码时输入
CurrencyType.会自动弹出已有的usd、cad等键名补全,打错键名时TS会立刻报错 - 不会出现基础索引签名里「访问不存在的键也不报错」的问题,类型安全性更高
如果你的TS版本低于4.9不支持satisfies,直接用第一个基础版本即可,完全能满足核心的约束需求。
内容的提问来源于stack exchange,提问作者h0bb5
相关产品推荐
相关产品推荐

