我可以在 TypeScript 中缩小范围吗?

Can I narrow this down in TypeScript?

我有一个实用函数来检查一个变量是否不为空或未定义,我希望 TypeScript 在通过检查时缩小输入变量的范围,例如:

public init(input?: string): void {
    function isSpecified(input: any): boolean {
        return (typeof input !== "undefined") && (input !== null);
    }

    if (isSpecified(input)) {
        let copiedString: string = input; // <-- Error; input is still 'string | undefined'
    }
}

如您所见,TS 并未消除字符串为 undefined 的可能性,即使该函数使这在逻辑上是不可能的。有没有办法让这个函数调用缩小 if 块内的 input

是的,您基本上只是编写了一个类型保护函数而没有添加类型保护。

变化:

function isSpecified(input: any): boolean

至:

function isSpecified(input: any): input is string

更一般地说,您可以使用同一事物的通用版本,:

function isSpecified<T>(input: null | undefined | T): input is T

您可以使用泛型类型保护函数:

public init(input?: string): void {
    function isSpecified<T>(input: null | undefined | T): input is T {
        return (typeof input !== "undefined") && (input !== null);
    }

    if (isSpecified(input)) {
        let copiedString: string = input; // OK
    }
}

虽然其他答案中建议的类型保护函数在很多情况下都运行良好,但在这种情况下,您还有另一个更简单的选择。而不是检查 (typeof input !== "undefined") && (input !== null) 只是内联检查 input != null.

很容易忘记,有时由双等号 ==!= 完成的类型转换实际上很有用:

function init(input?: string): void {
    if (input != null) {
        let copiedString: string = input; // <-- input is now 'string'
    }
}

在javascript或打字稿中以下都是true:

undefined == null
null == null
'' != null