Home > Back-end >  Typescript - Why a non-optional variable can be undefined in this case
Typescript - Why a non-optional variable can be undefined in this case

Time:12-20

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

enter image description here

playground

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.

  • Related