TypeScript Version: 3.8.0-dev.20191214
Search Terms: union, default value, literal, destructuring, optional
It surprised me a little bit not finding a duplicate myself. This is a frequent issue for us, though most of the time we can "fix" it with type assertion.
Code
interface Foo {
bar: 'yo' | 'ha' | undefined;
}
let { bar = 'yo' } = {} as Foo;
bar; // expecting `bar` to be `'yo' | 'ha'`, but gets `string` instead
Related Issues:
You should be using let { bar = 'yo' as const } = {} as Foo;, otherwise that 'yo' is just string value rather than the literal type yo.
Updated example: https://www.typescriptlang.org/play/index.html?ssl=1&ssc=1&pln=77&pc=72#code/JYOwLgpgTgZghgYwgAgGIHt3IN4FgBQyyARnFAFzIDkAnulcgD7UAWcDzAriACYQygIPANwEAvgQIAbCGBwkyyALzU6DOAGdkCdCA1yxynIc1pMo-AVJRhyAPR3kEAB4AHCAjCgA5sgAG1n7IYFjEKH609Eys7H4ANCScct6yWn76UD5BoPoQcDxAA
@rusev I am not looking for a workaround though. The compiler itself should just do the job without extra hint.
I'm 100% with you, but I think this is intended behavior :).
@ahejlsberg thoughts?
My immediate thought is that this is supposed to be equivalent, but isn't:
let bar = ({} as Foo).bar ?? 'yo'; // 'yo' | 'ha'
So, it seems like a fix is merited.
Most helpful comment
My immediate thought is that this is supposed to be equivalent, but isn't:
So, it seems like a fix is merited.