I'm using typescript to describe a variable but I'm encountering a strange issue:
import type { PlayerByIdQuery } from "generated/queries";
let skills: PlayerByIdQuery["playerById"]["skills"];
The error is:
Property 'skills' does not exist on type '{ __typename?: "Player" | undefined; id: string; number: string; skills?: { ...; }[] | ... 1 more ....'.ts(2339)
The type is:
export type PlayerByIdQuery = {
__typename?: "Query";
playerById?: {
__typename?: "Player";
id: string;
number: string;
skills?: Array<{
__typename?: "PlayerSkill";
description: string;
id: string;
playerId: string;
}> | null;
} | null;
};
It works if I change the type to (note the both missing | null
):
export type PlayerByIdQuery = {
__typename?: "Query";
playerById: {
__typename?: "Player";
id: string;
number: string;
skills?: Array<{
__typename?: "PlayerSkill";
description: string;
id: string;
playerId: string;
}>;
};
};
What am I doing wrong?
How can I correctly type let skills
?
CodePudding user response:
The problem is that playerById
is optional (may be undefined
) or null
.
And null['skills']
is not valid, which means that:
type A = { skills: string[] } | null
type B = A['skills'] // also not valid
So you need to explicitly remove the undefined
and null
from the type before you drill into it.
Luckily, typescript comes with a utility type for just that called NonNullable<T>
.
type A = { skills: string[] } | null
type B = NonNullable<A>['skills'] // now works fine
So now just apply this to your own types like so:
let skills: NonNullable<PlayerByIdQuery["playerById"]>["skills"] = [
{
__typename: 'PlayerSkill',
description: 'Fancy punch',
id: 'abc123',
playerId: 'def456'
}
]