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.