TypeScript如何定义包含固定name字段与任意数量Bar类型键值对的接口
报错根因
你定义的Foo是交叉类型,其中{ [key: string]: Bar }的字符串索引签名要求所有字符串类型的属性值必须是Bar类型,但你显式声明的name属性是string类型,和索引签名的约束冲突,因此触发类型不兼容报错。
解决方案
使用TS映射类型+Exclude工具类型,把固定属性从索引签名的键范围中排除,避免固定属性被索引签名约束:
export interface Bar { title?: string; [key: string]: string; } // 核心修改:排除name属性的索引签名约束 export type Foo = { name: string; } & { [key in Exclude<string, 'name'>]: Bar };
验证
修改后你给出的示例代码可以正常通过类型校验,不会报错:
const someObject: Foo = { name: 'John', randomProperty1: { a: 'a' }, randomProperty2: { b: 'b' }, // 其他任意Bar类型属性都可正常添加 };
扩展说明
如果后续需要新增多个固定属性,只需要把Exclude的第二个参数替换为固定属性名的联合类型即可,例如有name、id两个固定属性时写法如下:
export type Foo = { name: string; id: number; } & { [key in Exclude<string, 'name' | 'id'>]: Bar };
如果你的TS版本极低不支持上述写法,可以用兼容写法(不推荐,后续读取非固定属性时需要手动类型窄化):
export type Foo = { name: string; [key: string]: Bar | string; }
内容的提问来源于stack exchange,提问作者Henny Lee
相关产品推荐
相关产品推荐

