简体   繁体   中英

Can I narrow this down in TypeScript?

I have a utility function to check whether a variable is not null or undefined, and I want TypeScript to narrow down the input variable if it passes the check, for example:

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'
    }
}

As you can see TS is not removing the possibility of the string being undefined even though the function makes that logically impossible. Is there a way I can get this function call to narrow down input inside the if block?

You can use a generic type guard function:

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
    }
}

Yes, you've basically just written a typeguard function without adding the typeguard.

Change:

function isSpecified(input: any): boolean

to:

function isSpecified(input: any): input is string

More generally, you can use a generic version of the same thing, as mentioned by Ryan :

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

While the type guard function suggested in the other answers works well in many cases, in this case you have another much simpler option. Instead of checking for (typeof input !== "undefined") && (input !== null) just inline a check for input != null .

It's easy to forget that sometimes the type casting done by the double equal == and != can actually be useful:

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

In javascript or typescript the following are all true :

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM