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)
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.