Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How can I correctly type `let skills` using this generated typescript code?

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:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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?

>Solution :

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'
  }
]

See playground

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading