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

TypeScript编译报错:Property 'first' does not exist on type '{}'原因咨询

为什么这段TypeScript代码会抛出TS2339错误?

这个问题其实是TypeScript静态类型检查机制和JavaScript动态属性添加特性之间的典型冲突,咱们一步步拆解清楚:

错误原因分析

你初始化的object变量被TypeScript自动推断为空对象类型{}——这个类型里没有任何属性定义。虽然在JavaScript运行时,Object.defineProperty确实能给对象动态添加新属性,但TypeScript的编译检查是在代码执行前做的:它不知道你后续会给这个对象追加first属性,所以当你尝试访问object.first时,编译器就会抛出TS2339错误,提示该属性不存在于{}类型上。

而MDN的示例是纯JavaScript代码,没有静态类型校验环节,所以不会遇到这个问题,但放到TypeScript环境里就会触发类型规则校验。

解决方法

这里有几种常用的解决方案,你可以根据实际场景选择:

1. 使用类型断言(Type Assertion)

直接告诉TypeScript,这个对象最终会包含first属性:

var object = {} as { first: number };
Object.defineProperty(object, 'first', { 
  value: 37, 
  writable: false, 
  enumerable: true, 
  configurable: true 
});
console.log('first property: ' + object.first);

如果first属性是可选的,也可以写成{ first?: number }。

2. 提前定义对象类型

先声明一个包含目标属性的接口或类型,再把变量指定为这个类型:

interface MyObject {
  first?: number; // 标记为可选属性,因为初始对象里没有
}

var object: MyObject = {};
Object.defineProperty(object, 'first', { 
  value: 37, 
  writable: false, 
  enumerable: true, 
  configurable: true 
});
console.log('first property: ' + object.first);

3. 使用索引签名允许任意属性

如果你的对象可能会动态添加多个不确定的属性,可以用索引签名让TypeScript允许任意字符串键的属性:

var object: { [key: string]: any } = {};
Object.defineProperty(object, 'first', { 
  value: 37, 
  writable: false, 
  enumerable: true, 
  configurable: true 
});
console.log('first property: ' + object.first);

这种方式灵活性最高,但会失去部分类型校验的优势,适合属性不确定的场景。

4. 直接在初始化时定义属性(如果允许的话)

如果不需要用Object.defineProperty的特殊配置(比如writable: false),也可以直接在初始化时定义属性,让TypeScript自动推断正确类型:

var object = {
  first: 37
};
// 如果需要设置不可写,后续再用Object.defineProperty修改配置
Object.defineProperty(object, 'first', { writable: false });
console.log('first property: ' + object.first);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:35:40