TypeScript中Card类型赋值报错:slot1不存在于Card类型的原因?
TypeScript接口赋值错误原因解析
问题重现
定义的类型与接口
type CardId = 'slot1' | 'slot2' | 'slot3'; interface CardInfo { /* 具体定义省略 */ } interface Card { [_: CardId]: CardInfo; getByName: (name: string) => CardInfo | undefined; }
创建实例的代码
const myCard: Card = { slot1: { /* ... */ }, slot2: { /* ... */ }, slot3: { /* ... */ } };
报错信息
Type '{ slot1: { ... } ... ' is not assignable to type 'Card'.
Object literal may only specify known properties, and 'slot1' does not exist in type 'Card'.ts(2322)
错误原因
索引签名语法不符合规则
TypeScript的索引签名仅允许键类型为string、number、symbol或它们的联合类型,不能直接使用字符串字面量的联合类型(如CardId)。你写的[_: CardId]: CardInfo属于无效的索引签名,TypeScript无法正确识别slot1/slot2/slot3是Card接口允许的属性。索引签名与方法类型冲突
即使忽略键类型的问题,索引签名要求接口内所有属性的类型必须与索引值类型(这里是CardInfo)一致,但getByName是函数类型,和CardInfo完全不兼容。这会导致TypeScript直接忽略该索引签名,仅将getByName视为Card接口的唯一已知属性,因此你添加的slot1等属性会被判定为“未知属性”,触发报错。
修复方案
通过交叉类型拆分接口结构,先定义插槽属性的类型,再与方法接口合并:
type CardId = 'slot1' | 'slot2' | 'slot3'; interface CardInfo { /* 具体定义省略 */ } // 定义所有插槽的类型 type CardSlots = { [K in CardId]: CardInfo }; // 定义方法接口 interface CardMethods { getByName: (name: string) => CardInfo | undefined; } // 交叉合并得到最终的Card类型 type Card = CardSlots & CardMethods;
这样创建实例时,slot1等属性会被正确识别为合法属性,同时getByName方法也能正常添加。
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

