Typescript strictNullChecks检查函数之间的关系

Typescript strictNullChecks checking across functions

本文关键字:关系 之间 函数 strictNullChecks 检查 Typescript      更新时间:2023-09-26

启用--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。

//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");
    }
}

为什么会这样?有没有办法把一个函数标记为一个可以检查未定义和null的东西?如果可能的话,我想避免foo.bar!.baz。在这个例子中,很容易内联if/throw,但如果Foo有多个需要在多个函数中检查的可选属性,它就会变得重复。

为什么会这样?

你可以想象TypeScript试图内联这个函数,但是为了得到一个准确的结果,你需要内联validateFoo调用的每个函数——这可以任意深入。

实际上在TypeScript的问题跟踪器中有一个完整的讨论。

是否有办法将函数标记为可以检查未定义和null的东西?

Sort of -有类型谓词,如果函数返回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;
}