TypeScript:在运行时区分未设置和不存在的属性

时间:2017-12-21 23:27:33

标签: javascript typescript

我有一个类,它具有键入的属性,但没有设置默认值,如:

export class Person {
   age: number;
}

在运行时,我有一个JSON对象,我想根据类签名测试它们的属性,以确保它是该类的已定义属性之一。

{
   "age": 42,
   "propertyNotInClass": "oops!"
}

是否绝对有必要为类中的每个属性设置默认值以进行测试?

[edit]:在我目前的用例中,我只需要知道对象是否已定义。虽然我有兴趣知道这种类型是否可以进行测试。我知道这本身并不是TypeScript的一部分,所以会涉及某种诡计。

3 个答案:

答案 0 :(得分:1)

我认为这是打字稿,因为你在问题中使用了typescript标签。

简短的回答是,原因如下:

Typescript被转换为JS。所以在运行时,class的概念不存在。如果要在运行时检查JSON,则必须逐个检查所需的属性。

这是您的person课程将转移到的内容:

define(["require", "exports"], function (require, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    var Person = /** @class */ (function () {
        function Person() {
        }
        return Person;
    }());
    exports.Person = Person;
});

我的意思是逐个检查,在这种情况下,只有一个属性

class Person {
    age: number;

    static isPerson(obj: Object): boolean {
      return !!obj.hasOwnProperty('age');
    }
}
Person.isPerson({ age: '32' }); // returns true
Person.isPerson({}); // returns false

可以通过变压器获取所有属性(尚未尝试过)请在此处阅读更多内容:https://github.com/Microsoft/TypeScript/issues/13764

答案 1 :(得分:1)

TypeScript只能帮助您捕获类型错误并在编译时强制实现某些接口。但是,它无法在运行时验证对象的结构。您必须使用vanilla JavaScript方法检查属性是否存在或者是否具有所需的值。

答案 2 :(得分:1)

您可以使用TypeScript 用户定义的类型防护来桥接运行时和编译时。

function isPerson(obj: any): obj is Person {
  return obj && typeof obj.age === 'number';
}

注意obj is Person的特殊返回类型,它允许您创建缩小类型推断的条件:

if (isPerson(maybePerson)) console.log(maybePerson.age);
else console.log('not a Person');

https://www.typescriptlang.org/docs/handbook/advanced-types.html#user-defined-type-guards