我想在很大的代码库中开始使用strictNullChecks
标志。这绝对是一个非常有用的标志,但是我开始在大多数接口定义中包括null类型。也许这是个人的看法,因为我以前从未使用过该标志,但是它开始降低了代码的可读性(imho)。我有空无处不在的感觉。所有这些都源自返回<type> | null
的函数,该函数在函数调用堆栈中向上传播,迫使我在接口中也包含空类型。
大多数时候,我都有可选的可为空字段,例如:
interface X {
field?: string | null
}
当null和undefined都是伪造的值时,这种事情有点奇怪。
我曾考虑过用未定义的空类型替换空类型,例如:<type> | undefined
从可选的接口字段中删除空类型,所以我只有:
interface X {
field?: string
}
但是后来我失去了null的语义值,这是我想要维护的。
那么,您如何看待strictNullChecks?您是否发现这类字段field?: string | null
有点怪异,还是您喜欢并感到满意?
答案 0 :(得分:2)
我个人建议完全删除null
,而改用undefined
。
如果您的应用程序中null
和undefined
值之间存在语义差异,则可能会引起混淆(在TS和纯JS中)。如果您不这样做,而您只是随机返回null
/ undefined
,则只使用其中一个会更简单,更一致。
就使用哪种方式而言,我建议使用undefined
,主要是因为TypeScript对它的支持更好一些(即?
)。有一些参数仅使用null
来代替,它更加冗长,并且使用undefined
作为丢失数据的指示符通常很方便,因为它是每个未初始化变量/字段的默认值,而那些< em>应该通常具有与明显不可用的数据相同的语义和行为。
答案 1 :(得分:0)
我同意蒂姆·佩里(Tim Perry)的回答,即只使用一个-null或undefined-我的建议还坚持使用undefined,主要是因为您无法避免,因为这是缺少字段和未初始化的值变量。
对于默认函数参数,null也无效:
function f(x = 1) {
// ...
}
这里f(undefined)
会将x
设置为1
,但是f(null)
不会!
null的唯一参数是JSON不支持显式undefined,但这不是像当您反序列化需要显式null值(而不是缺少值,实际上意味着未定义)的JSON时那样的问题。可以轻松地将其转换。
在我的项目中,我尽量使用linter配置禁止空值,例如对于TSLint:
"no-any": true,
"no-null-keyword": true
这个女巫strictNullChecks
可以很好地避免多种错误。
请记住,NULL的创建者称其为十亿美元的错误。具有两个无效值甚至更糟。但是,如果您只有一个(如未定义)和,并且在TypeScript中使用严格的null检查,那么可以避免大多数语言通常由null / undefined引起的问题。
无论您要使用undefined,null还是同时使用这两者,我都强烈建议您始终使用strictNullChecks,因为没有它,您的代码就不是真正的安全类型。
有关TypeScript 2.0 release notes的有关null和undefined的类型的信息,请参见:
类型检查器以前认为是null,并且未定义可分配给任何内容。实际上,null和undefined是每种类型的有效值,因此不可能专门排除它们(因此无法检测到对它们的错误使用)。 [强调]
默认情况下未启用该功能,以便与添加新的检查null和undefined的方法之前编写的旧代码向后兼容。
考虑以下简单功能:
const f = (x: string) => x.toLowerCase();
没有严格的标志,不输入安全。 使用运行时TypeError异常,它可能崩溃:
TypeError: Cannot read property 'toLowerCase' of undefined
带有严格标志:
const f = (x: string | null) => x.toLowerCase(); // COMPILE TIME ERROR
const f = (x: string | null) => x && x.toLowerCase(); // OK and safe
有关更多信息,请参见: