Given these two types:
type Prospect = {
name: string;
}
type Client = {
name: string;
account: string;
}
Let's create a union where kind
acts as the discriminator:
type Union =
| {kind: "prospect", persons: Prospect[]}
| {kind: "client", persons: Client[]};
const {persons, kind} = {} as Union
Type narrowing works as expected when accessing persons
.
if (kind === "client") {
persons.map(person => { // person: Client
person.account // All good
})
}
It, however, fails to work after accessing an individual element from persons
.
const person = persons[0]
if (kind === "client") { // person: Prospect | Client
person.account // Error
}
How can I achieve type narrowing after I have already accessed an array? I could add a kind
field to Prospect
and Client
but that seems redundant given that persons is always an array of Prospect
or Client
and not a mix of both.
CodePudding user response:
You can move person access inside type guard:
if (kind === "client") { // person: Prospect | Client
const person = persons[0]
person.account // Ok
}
In your case of
const person = persons[0]
if (kind === "client") { // person: Prospect | Client
person.account // Error
}
Typescript cannot guess that person/persons[0] didn't mutate and change type between assignment and type guard, so it cannot safely narrow type.