2

Imagine we have the following types:

interface User {
    name: string
}

interface Session {
    id: string
    startTime: number
    moderator?: User
    student: User
    instructor: User
    observer: User
}

Is there a way to get a keyof from Session, that's only for the keys that are of type User ? In this case that would be "moderator" | "student" | "instructor" | "observer" but not "id" | "startTime". Let's say in any version of TypeScript (if this has changed or there's a language feature in the works), but I'm using 4.1.2 for reference.

Edit for Associated Question
The linked question does answer this question completely although I feel like this more generic phrasing is useful. I also made one of the User fields optional because my real code has optionals and that threw me. A one liner for my specific issue (based off the linked question) is:

type UserKeys = {[K in keyof Session]-?: Session[K] extends User|undefined ? K : never}[keyof Session];

*Note the -? and User|undefined if you have optionals.

Shawn Aten
  • 351
  • 4
  • 10
  • 1
    Translating the answer from the other question here yields [this code](https://tsplay.dev/DmMo1w). – jcalz Feb 10 '21 at 19:32
  • 1
    The associated question does answer my question although I do think the titles could be improved as the answer is not string specific. – Shawn Aten Feb 10 '21 at 20:13

1 Answers1

1

Yes there is using mapped types

type UserKeys = {
  [Key in keyof Session]: Session[Key] extends User ? Key : never
}[keyof Session]

apieceofbart
  • 2,048
  • 4
  • 22
  • 30