生成的打字稿似乎是多余的,但我打赌它不是

时间:2017-12-12 19:43:56

标签: javascript typescript nswag

NSwag生成的typescript类具有如下定义的属性:

export class Foo {
  id?: number | undefined;
}

我知道?表示id属性是可选的。我希望这些属性定义与上面的有效相同:

id?: number
id: number | undefined

这些定义之间有什么区别?为什么NSwag会选择第一个?

3 个答案:

答案 0 :(得分:3)

使用?标记属性表示它可能会或可能不会在对象上声明 。给它一个可能的undefined类型表示,即使它被声明,它也可能没有值。

id?: number说如果在对象上声明属性,它将具有数值。

id: number | undefined声明属性已声明但可能是数字或没有定义的值。

id?: number | undefined声明属性可能会或可能不会被声明,即使声明属性,也可能是数字或没有定义的值。

您可以拥有对象obj = {id: undefined},其中id仍然存在但没有价值,或者您可以obj = {}id未声明对象上。在任何一种情况下typeof obj.id === 'undefined'都是正确的,但只有在id中才会成为对象的可枚举键。

但是,在我的实验中,Typescript编译器似乎对这些细节有些松散。即使在第三种情况下,它似乎假设一个属性被声明它也被定义。

要解决问题的根,它不是多余的,而是指示特定的对象属性。当使用标有?undefined的类属性时,您不能仅仅因为声明它具有值而假设它。检查它的值的最佳方法是检查数字类型:typeof obj.id === 'number',因为对数字的真正检查从来都不是一个好主意(0 == false)。简单地遍历对象(for i in obj)或检查对象上的属性(if('id' in obj))也是不安全的。

答案 1 :(得分:2)

请考虑此片段以查看差异:

interface Foo {
    id?: number | undefined;
}

function giveMeFoo(foo: Foo): void {
    if ("id" in foo) {
        // Here, foo.id has type: number | undefined
    }
    if (foo.id) {
        // Here, foo.id has type: number
    }
}

interface Bar {
    id?: number;
}

function giveMeBar(bar: Bar): void {
    if ("id" in bar) {
        // Here, bar.id has type: number
    }
    if (bar.id) {
        // Here, bar.id has type: number
    }
}

基本上,可选属性(使用?)意味着该属性可能不存在于对象上,但如果属性,则列出了类型。如果你只是检查属性的存在(而不是它的真实性),那么结果仍然是未定义的。

所以我猜测NSwag产生该定义的原因是因为不仅对象中缺少属性id,而且即使对象具有id属性,它也可能明确设置为undefined

答案 2 :(得分:0)

问号会使该参数成为可选项,因此将{}传递给期望Foo对象在TS编译器中不会中断的东西。如果它不是可选的并且可能未定义,{}会导致类型错误,而{id}则不会。