Home > Back-end >  Pick of a nested Pick | Typescript
Pick of a nested Pick | Typescript

Time:09-02

We have 2 interfaces: File and User. 1 File has 1 User. We want to pick data from the user and the file.

interface DownloadFile {
  id: string
  name: string
  user: User
  createdAt: Date
}

interface User {
  id: string
  name: string
  isEmailValidated: boolean
  unsubscribe: boolean
  email: string
}
type QueryResponse = {
  file: Pick<DownloadFile, 'id' | 'name'> & {
    user: Pick<DownloadFile['user'], 'id' | 'name' | 'email'>
  }
}

This is working fine.

How can we prevent a typo in the nested object name (userTYPO) and get an error:

type QueryResponse = {
  file: Pick<DownloadFile, 'id' | 'name'> & {
    userTYPO: Pick<DownloadFile['user'], 'id' | 'name' | 'email'>
  }
}

CodePudding user response:

You need some construct to constrain the set of possibilities here. And if you want to constrain a type then you must use a generic type with that constraint. That means that this simple snippet:

type A = B & C

Isn't going to work because there is no way to constrain B and C.

So what you need is a type that makes this type for you.

There are a lot of ways to do this. Here's one.

type MakeFileUserQueryResponseType<
  T extends {
    fileKeys: keyof DownloadFile,
    userKeys: keyof DownloadFile['user'],
  }
> = {
  file: Pick<DownloadFile, T['fileKeys']> & {
    user: Pick<DownloadFile['user'], T['userKeys']>
  }
}

Which you would use like so:

type QueryResponse = MakeFileUserQueryResponseType<{
  fileKeys: 'id' | 'name',
  userKeys: 'id' | 'name' | 'email'
}>

You specifically require a strict type as constraint of T, and anything that fails to conform to that will be a type error.

See Playground

  • Related