Search code examples
typescriptunion-types

Getting error with type using Typescript union


type myType = { subtitle: string, title: string } | {};

const someVar: myType = { title: 'some-title', subtitle: 'some subtitle'}

const myTitle: string = someVar?.title;

I get this type error when I try to access title value from someVar object. Now, what I don't understand is why wouldI get this type error. I checked the documentation but I don't understand its implication. Union means I can specify possible types but here behaviour seems to be different. Any idea why's that

Property 'title' does not exist on type '{} | { subtitle: string; title: string; }'.
  Property 'title' does not exist on type '{}'.ts(2339)

Solution

  • Now, what I don't understand is why wouldI get this type error.

    Because {} doesn't have a property called title, and you've said that someVar's type is myType, which is either { subtitle: string, title: string } or {}. Since it might be {}, you can't access title without first making sure it's there. From the handbook:

    TypeScript will only allow you to do things with the union if that thing is valid for every member of the union.

    Accessing title isn't valid for {}, just { subtitle: string, title: string }.

    To use title, you can use a type guard to narrow the type (details about narrowing here in the handbook):

    if ("title" in someVar) {
        // ...you can use `someVar.title` (and/or `someVar.subtitle`) here...
    }
    

    Within that if body, TypeScript knows that someVar's type is { subtitle: string, title: string }, not {}, thanks to the condition.

    captain-yossarian points out that this question's answers may be useful to read through as well, around how excess property checks apply to unions and the StrictUnion flag.