4

Suppose I have this interface

interface MyInterface {
   val1: string
   val2: string
   val3: number
   val4: string
   val5: Date
}

I want to make a type that is the keys of the MyInterface but only the keys that are strings:

type myType = keyof MyInterface //where key === typeof 'string'
// myType: 'val1' | 'val2' | 'val4'

How could I do something like this?

1 Answer 1

10

You can use a mapped type to preserve only specif keys and then do a keyof on the resulting type

type myType = keyof {
    [P in keyof MyInterface as MyInterface[P] extends string ? P: never]: any
}

Playground Link

You could also make it generic


type KeyOfType<T, V> = keyof {
    [P in keyof T as T[P] extends V? P: never]: any
}

type myType = KeyOfType<MyInterface, string>
type myType2 = KeyOfType<MyInterface, number>

Playground Link

The as clause of a mapped type allows us to manipulate the name of the key. If the key is mapped to never the key gets removed from the resulting type. You can find more info in this PR

Sign up to request clarification or add additional context in comments.

2 Comments

The "old" way would also work 🙂 type KeyOfType<T, V> = { [P in keyof T]: T[P] extends V ? P: never }[keyof T]
@AlekseyL. yeah . it would . But the new way is way more readable IMO

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.