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

TypeScript中属性赋值正常但访问报TS(7053)错误的原因咨询

TypeScript类型错误解析:赋值允许但访问报错的原因

报错信息

Element implicitly has an 'any' type because expression of type '"bla"' can't be used to index type 'Record<string, any> | PropertiesI'.
  Property 'bla' does not exist on type 'Record<string, any> | PropertiesI'.ts(7053)

对应代码

interface PropertiesI {
  bar: string;
}

interface ParentSchemaI {
  foo: string;
  properties: PropertiesI | Record<string, any>;
}

const mySchema: ParentSchemaI = {
  foo: "baz",
  properties: {
    bla: "blabla", // 此处未报错
  },
};

const attempt = mySchema.properties["bla"]; // 此处却触发错误?

原因分析

赋值阶段的类型匹配逻辑

当你直接给properties赋值{ bla: "blabla" }时,TypeScript会自动将这个对象字面量与PropertiesI | Record<string, any>联合类型做匹配。由于Record<string, any>允许任意字符串键值对,这个对象字面量可以被完美推断为Record<string, any>类型,因此赋值操作通过类型检查,没有报错。

访问阶段的联合类型索引规则

TypeScript对联合类型的索引访问有严格规则:只有当联合类型的所有分支都支持该索引时,才能直接访问该属性。这里的联合类型是PropertiesI | Record<string, any>:

  • PropertiesI仅定义了bar属性,不存在bla,无法通过"bla"索引;
  • 虽然Record<string, any>允许任意索引,但因为联合类型中存在不支持该索引的分支(PropertiesI),TypeScript无法保证访问"bla"的安全性,因此抛出ts(7053)错误。

解决办法

  • 类型断言:明确指定当前properties的类型为Record<string, any>:
const attempt = (mySchema.properties as Record<string, any>)["bla"];
  • 类型守卫缩小范围:通过条件判断区分两种类型,让TypeScript自动推断正确的类型:
if ("bar" in mySchema.properties) {
  // 此处mySchema.properties被推断为PropertiesI类型
} else {
  // 此处被推断为Record<string, any>类型,可安全访问bla
  const attempt = mySchema.properties["bla"];
}
  • 调整类型定义:如果业务允许,让PropertiesI继承Record<string, any>,或者直接将properties的类型改为Record<string, any>:
// 方案1:继承
interface PropertiesI extends Record<string, any> {
  bar: string;
}

// 方案2:简化类型
interface ParentSchemaI {
  foo: string;
  properties: Record<string, any>;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 16:35:28