启用--strictNullChecks
后,如果检查在单独的函数中发生,则tsc似乎无法推断可选属性未定义。 (参见示例,因为我很难清楚地说明这一点。)
给定一个带有可选属性的接口,如
interface Foo {
bar?: {
baz: string;
};
}
以下代码编译:
//compiles
function doStuff(foo: Foo) {
if (foo.bar === undefined) {
throw new Error("foo.bar must be defined");
}
foo.bar.baz;
}
这段代码没有,因为tsc认为foo.bar可以是未定义的:
//does not compile, foo.bar can be undefined
function doStuff2(foo: Foo) {
validateFoo(foo);
foo.bar.baz;
}
function validateFoo(foo: Foo) {
if (foo.bar === undefined) {
throw new Error("foo.bar must be defined");
}
}
这是为什么?有没有办法将函数标记为可以检查undefined和null的函数?如果可能的话,我想避免foo.bar!.baz
。在示例中,很容易内联if / throw但是如果Foo有多个可选属性需要在多个函数中检查它会重复。
答案 0 :(得分:2)
为什么会这样?
你可以想象TypeScript试图为此内联函数,但是为了获得准确的结果,你需要内联validateFoo
调用的每个函数 - 这可以任意深入。
实际上有关于此here on TypeScript's issue tracker的完整讨论。
有没有办法将函数标记为可以检查undefined和null的东西?
排序 - 有类型谓词,如果函数返回true
,它们会告诉TypeScript参数的类型是什么。
function validateFoo(foo: Foo): foo is { bar: { baz: string } } {
if (foo.bar === undefined) {
throw new Error("foo.bar must be defined");
}
return true;
}
您可以按如下方式使用它:
function doStuff(foo: Foo) {
if (!validateFoo(foo)) {
throw foo;
}
foo.bar.baz;
}