typescript - 未初始化的 TypeScript 类属性不会被迭代

标签 typescript reflection typescript-2.5 class-properties

我有以下类(class):

export class SomeModel {
  prop1: number;
  prop2: number;
  comment: string;
}

以及以下动态获取其属性的方法:

getTypeProperties<T>(obj: T): string[] {
    const ret: string[] = [];
    for (const key in obj) {
      if (obj.hasOwnProperty(key))
        ret.push(key);
    }
    return ret;
}

以下调用返回一个空数组:

getTypeProperties(new SomeModel());

但是,如果我用 null 显式初始化所有属性,属性将正确返回:

export class SomeModel {
  prop1: number = null;
  prop2: number = null;
  comment: string = null;
}

问题:这是正常行为吗?或者是否有 TypeScript 编译器开关来切换它?

我不知道它是否相关,但这里是 tsconfig.json 内容:

{
  "compileOnSave": false,
  "compilerOptions": {
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "target": "es5",
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2017",
      "dom"
    ]
  }
}

最佳答案

这是设计使然,字段声明不输出任何 JavaScript 代码,它们只是告诉编译器该字段存在(即,当我在代码中使用它时,预计不要提示)并且是某种类型。在您第一次分配该字段之前,它不会存在于实例中,因此不会被迭代。如果您初始化该字段,它的值将被分配给构造函数中的实例,因此将成为可迭代的。

正如您所发现的,解决此问题的最简单方法是为字段分配一个值,如果只有值 undefined

我们可以在为 ES5 生成的代码中看到这种行为。例如这个类

class A {
    nonInitField: number;
    initField = 0;
    test() {
        this.nonInitField = 0;// Can be used, and will be iterable after it is assigned
    }
}

生成此代码:

var A = /** @class */ (function () {
    function A() {
        this.initField = 0; // Iterable right away as it is assigned in the constructor
    }
    A.prototype.test = function () {
        this.nonInitField = 0; // Can be used, and will be iterable after it is assigned
    };
    return A;
}());

关于typescript - 未初始化的 TypeScript 类属性不会被迭代,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51057508/

相关文章:

java - 动态创建 POJO/bean 并使用 CGLib 设置值

c# - 使用列表项内容作为字符串名称

node.js - Typescript:编译的 .js 需要定义文件中的类和接口(interface)

javascript - 错误:找不到模块 Mocha

javascript - 循环遍历对象数组并找到特定键

javascript - 如何在 typescript 中编写一个类型,其中一个值的类型将取决于对象中另一个值的类型

嵌套对象的 typescript 字符串点表示法

c# - 所有事件的 ThreadLocal<T> 和 [ThreadStatic] 引用的列表

typescript - 运算符 '!==' 不能应用于类型 "A"| "B",但是 '===' 可以吗?

angular - 单击选项卡时,我需要在 angular2 中加载特定组件