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

Typescript reference 'this' type of an object

Consider the following type:

type UserList = {
  userIds: string[]
  userData: {
    [UserId in UserList['userIds'][number]]: {
      userId: UserId
      username: string
    }
  }
}

with that I want to tell TypeScript compiler two things:

  1. userData keys must exist in userIds
  2. userId field must be equal to the key of the same entry

I feel that I need some kind of this or self keyword instead of UserList

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

>Solution :

I don’t believe it’s possible to refer to the exact string values inside userIds without resorting to using a generic type parameter:

type UserList<T extends ReadonlyArray<string>> = {
  userIds: T
  userData: {
    [UserId in T[number]]: {
      userId: UserId
      username: string
    }
  }
}

And your type definition would have to look as follows:

const a: UserList<['hello']> = {
    userIds: ['hello'],
    userData: {
        hello: {
            userId: 'hello',
            username: 'username'
        }
    }
}

If you don’t want to specify the user IDs twice (inside the generic parameter and inside the actual UserList variable), you have to use a wrapper function:

function asUserList<T extends ReadonlyArray<string>>(list: UserList<T>) {
  return list;
}

const a = asUserList({
    userIds: ['hello'] as const,
    userData: {
        hello: {
            userId: 'hello',
            username: 'username'
        }
    }
})

If you don’t use a generic parameter and instead try to use the this type inside an interface like this:

interface UserList {
  userIds: string[]
  userData: {
    [UserId in this['userIds'][number]]: {
      userId: UserId
      username: string
    }
  }
}

It wouldn’t work because this['userIds'] would always resolve to the weak string[] type, not a specific set of strings that would allow you to strongly type userData based on the exact value of userIds.

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