TypeScript Version: 3.5.1
Code
interface DataType{
display_name: string | null
}
function myName(data :DataType) : string{
if( !!data.display_name === false ) return 'No Name'
return data.display_name
}
Expected behavior:
Typescript shouldn't complain about return data.display_name because I covered the null before this.
Actual behavior:
It saying Type 'string | null' is not assignable to type 'string'.
Type 'null' is not assignable to type 'string'. on return data.display_name
Playground Link:
You can see the result here.
Type guards only trigger on certain syntactic constructs, and there's no reason to write the form
if (!!x === false)
, so TS doesn't recognize it.
I think this is a common way to coerce null & undefined & string to boolean. This is one of the use cases that I faced with this issue
I'm not sure about how TS can solve this, but I think this is a common way to write so for satisfying TS we need to add some workaround like this.
I also checked !val is working as expected but !! is not working as I said.
!! is a common way to coerce to boolean, and Typescript does recognize it for narrowing:
https://www.typescriptlang.org/play/index.html#code/CYUwxgNghgTiAEA3W8oC54G94A8MBZ4BfeAH3gDsBXCCAKDoEsAzeACgEIOoBKLO+INQBueAHoxWXAWJ0SICAGcEmAUKiiJlGvSJ0gA
Putting === false or === true in an if is the thing that nobody does.
@nattthebear So maybe I'm the only one writes in this way :)
In your example, if we put a outside of the else it doesn't work properly in function at least. see this
Anyways my point is something that is working in JS, expected to work on TS too. this is a valid case IMO.
There's no limit to how elaborate you could make your condition, but TS pays a performance and complexity cost for every form it supports, and there's just no reason to write !!x === false instead of !x. If this were idiomatic and common we would consider it, but it appears to be atypical (i.e. you are the first person to notice).
Your second link gets into an unrelated question: falsy checks on a string don't remove string from the possibilities because "" is falsy. This has nothing to do with the === false construct and TS is behaving correctly.
Most helpful comment
Type guards only trigger on certain syntactic constructs, and there's no reason to write the form
, so TS doesn't recognize it.