if I create a non-optional variable of type "data". Why the value in the next case can be undefined and how can I prevent this from happening and for example throw an error if the value is not really a value? (without manually checking each value in the case that I have many variables inside the type).
`
type data = {
nonOptional: string
optional?: string
}
var val: string | any = "example"
val = undefined
var data: data = {nonOptional: val};
console.log("nonOptional value: " data.nonOptional)
` output: "nonOptional value: undefined"
CodePudding user response:
This is known as union type collapse
If you try to union a type with another wider type or any
, it will collapse to wider type or any
You can think any
as the widest type out there
the more narrow a type, the safer it is (and harder to code, safety always comes with cost)
so avoid any
if possible, because it is the laziest and least safe type out there
CodePudding user response:
Don't use any
When you define the type of val
as the union string | any
you are saying that it is one of two things: either it's a string
or it is any
which is assignable to anything.
You are effectively short-circuiting type-checking of val
and saying that anything goes. You can now assign any value to val
, including undefined
, because undefined
is assignable to any
.
So now let's think about what is happening here:
var data: data = {nonOptional: val};
We know that whatever value we put on the nonOptional
property must be assignable to string
. We know that val
has a union type string | any
. In order to pass type-checking, both possibilities of the union must be assignable to string
. string
is assignable to string
. any
is also assignable to string
because any
is assignable to everything. Both branches of our union pass, so there is no error.
We need to give val
an accurate type that represents its possible values.
var val: string | undefined = "example"
val = undefined
The union string | undefined
covers all possibilities.
When we do that, we get the error that you expect:
var data: data = {nonOptional: val};
Type 'undefined' is not assignable to type 'string'.(2322)
The expected type comes from property 'nonOptional' which is declared here on type 'data'
As explained before, both possibilities of the union must be assignable to string
. In this case undefined
is not assignable to string
and therefore type-checking fails.