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

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)

错误原因

  1. 索引签名语法不符合规则
    TypeScript的索引签名仅允许键类型为string、number、symbol或它们的联合类型,不能直接使用字符串字面量的联合类型(如CardId)。你写的[_: CardId]: CardInfo属于无效的索引签名,TypeScript无法正确识别slot1/slot2/slot3是Card接口允许的属性。

  2. 索引签名与方法类型冲突
    即使忽略键类型的问题,索引签名要求接口内所有属性的类型必须与索引值类型(这里是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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 22:33:31