NSwag生成的typescript类具有如下定义的属性:
export class Foo {
id?: number | undefined;
}
我知道?
表示id
属性是可选的。我希望这些属性定义与上面的有效相同:
id?: number
id: number | undefined
这些定义之间有什么区别?为什么NSwag会选择第一个?
答案 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}则不会。