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

如何在TypeScript中强制对象类型仅包含字符串键?

解决TypeScript中强制对象类型仅含字符串键并修复模板字符串报错问题

问题分析

你的代码中StrKeyObj仅将非字符串键对应的值设为never,但并未真正排除symbol或number类型的键。keyof Models仍可能包含symbol类型,而模板字符串${keyof Models}.${Method}要求拼接项必须是字符串类型,因此触发报错。

解决方案

方案1:约束对象仅允许字符串键(彻底禁止非字符串键)

定义工具类型明确禁止number和symbol类型的键,确保keyof Models仅为字符串:

// 仅允许字符串键的对象类型,禁止number/symbol键
type StringKeyedObj<T = any> = {
  [K in string]: T;
} & {
  [K in number | symbol]: never;
};

export interface EventHandler<
  Method extends 'create' | 'update', 
  Models extends StringKeyedObj = StringKeyedObj
> {
  on: `${keyof Models}.${Method}`; // 此时keyof Models仅为string,无报错
  main(): void;
}

验证:

  • 传入含非字符串键的对象会触发约束报错:
    const testSym = Symbol('demo');
    type InvalidModel = { [testSym]: number; name: string };
    // 报错:类型“InvalidModel”不满足约束“StringKeyedObj<any>”
    type BadHandler = EventHandler<'create', InvalidModel>;
    
  • 传入合法字符串键对象正常工作:
    type ValidModel = { user: string; post: number };
    type GoodHandler = EventHandler<'update', ValidModel>;
    // on的类型为 "user.update" | "post.update",符合预期
    

方案2:过滤非字符串键(兼容数字键转为字符串的场景)

如果允许对象存在数字键(TypeScript会自动将数字键转为字符串),仅需在模板字符串中提取字符串类型的键:

export interface EventHandler<
  Method extends 'create' | 'update', 
  Models extends Record<string, any> = Record<string, any>
> {
  on: `${Extract<keyof Models, string>}.${Method}`;
  main(): void;
}

说明:Extract<keyof Models, string>会从keyof Models中过滤出仅字符串类型的键,确保模板字符串拼接合法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 09:33:24