I'm puzzled by why the type for variable a below is not LoadStatus even though I explicitly put it in the declaration:
type LoadStatus = 'succeess'|'failure'|null;
let a: LoadStatus = null;
let b = null as LoadStatus;
a; // type is null
b; // type is LoadStatus
I inspected the types using Typescript playground.
This is by design. If that were not the case, miscellaneous type mechanisms would be significantly less useful. For example:
type LoadStatus = 'success' | 'failure' | null;
let a: LoadStatus = null;
let b = null as LoadStatus;
a ; // type is null
b; // type is LoadStatus
// null is converted to 'failure', so that always a string is returned
type ConvertLoadStatus<T extends LoadStatus> = T extends null ? 'failure' : T;
type resultA = ConvertLoadStatus<typeof a>; // failure;
type resultB = ConvertLoadStatus<typeof b>; // 'success' | 'failure', not very helpful
a = 5; // a is still not assignable to other things than described, so typing still protects the variable
Another example would be if statements when checking for null or undefined:
type ExampleType = {a: string, b: number} | null;
function doSomething(a: ExampleType) {
if(a != null) {
a // a is {a: string, b: number}
a.a // a can now be accessed
// How would we ever be able to access a if it always stayed ExampleType?
}
a.a // Object is possibly 'null'
}
Edit: As @Boug pointed out, it's all described under narrowing.
This is called narrowing union type.
Check the documentation here and you will understand why it is as it is Docu
The following example is very much like yours narrowing example
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With