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

TypeScript类库与Angular Web应用对象实例化差异:属性缺失

问题原因与解决方案

核心原因:TypeScript编译配置差异

出现这种差异的关键是**useDefineForClassFields编译选项**的设置不同:

  • 类库项目中,该选项大概率为false,TypeScript会将类的属性声明编译为构造函数内对实例的赋值(如this.firstName = undefined),因此实例会包含这些属性键,Object.keys能正常获取。
  • 常规Angular Web应用默认开启了useDefineForClassFields: true(尤其当target设置为ES2022及以上时),此时类属性会被编译为ES6+原生类字段,未显式初始化的属性不会被添加到实例对象中,所以Object.keys返回空数组,控制台显示空对象。

此外,Angular类库与Web应用的默认tsconfig配置本身存在差异:类库的tsconfig.lib.json通常为了兼容更多环境,会采用更保守的编译设置;而Web应用更倾向于使用现代JS特性,默认启用该选项。

解决方案

方案1:修改Web应用的TypeScript配置

在Web项目的tsconfig.json(或tsconfig.app.json)中添加/修改以下配置:

{
  "compilerOptions": {
    "useDefineForClassFields": false
  }
}

修改后重新编译项目,类实例会自动带上未初始化的属性键,行为将和类库一致。

方案2:显式初始化类属性

如果不想修改全局编译配置,可以在类的属性声明时显式赋值undefined,确保属性被添加到实例中:

class User {
    firstName: string = undefined!; 
    lastName: string = undefined!;
}

这里的!是非空断言,用于规避TypeScript的严格初始化检查(如果开启了strictPropertyInitialization)。

方案3:运行时获取类属性的替代方式

如果需要在useDefineForClassFields: true的前提下获取类的属性列表,可以提前定义类的属性名数组,手动为实例添加属性:

// 提前定义属性列表
const USER_PROPERTIES = ['firstName', 'lastName'];

function instantiate<T extends Object>(constructor: new () => T, properties: string[]) : T {
    const obj = new constructor();
    // 手动为实例添加属性
    properties.forEach(key => obj[key as keyof T] = undefined);
    console.log('Object is:', obj);
    console.log('Keys are:', Object.keys(obj));
    return obj;
}

// 使用时传入属性列表
instantiate(User, USER_PROPERTIES);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 01:37:26