Typescript strictNullChecks跨函数检查

时间:2016-11-14 04:50:13

标签: javascript typescript typescript2.0

启用--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有多个可选属性需要在多个函数中检查它会重复。

1 个答案:

答案 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;
}