4

NSwag 生成 typescript 类,其属性定义如下:

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

我知道?意味着该id属性是可选的。我希望这些属性定义实际上与上述相同:

id?: number
id: number | undefined

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

4

3 回答 3

3

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

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

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

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

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

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

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

于 2017-12-12T20:05:53.047 回答
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.

于 2017-12-12T20:08:43.940 回答
0

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

于 2017-12-12T21:22:52.127 回答