Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The type to indicate keys that be set specific type value in Typescript

Tags:

typescript

I want to make a type KeyOfType<M, T> for keys that be set specific type value.

interface MyTypeMap {
    "one": 1;
    "two": "hello";
    "three": 3;
    "four": "world";
    "five": 5;
};

type KeyOfType<M, T> = ....; // ?????

type Foo = KeyOfType<MyTypeMap, string>; // 'two' | 'four'
type Bar = KeyOfType<MyTypeMap, number>; // 'one' | 'three' | 'five'

I tried like below, but it's not working...

type KeyOfType<M extends {
  [key in keyof M]: any;
}, T> = M extends {
  [key in infer R]: T;
} ? R : never;

Is there any way to solve this?

like image 305
grace Avatar asked Dec 17 '21 05:12

grace


1 Answers

I would use key remapping here, since remapping a key to never will remove it from the resulting type:

type KeyOfType<M, T> = keyof {
  [K in keyof M as M[K] extends T ? K : never]: K
};

This iterates over every key K in M, and checks of the value M[K] extends the T type. If it does, keep the key, else remap the key name to never, removing it. The value type doesn't matter since you only want the keys, so just shoving K in there seems fine. Then cram a keyof at the start to pull out just the keys.

Playground

like image 89
Alex Wayne Avatar answered Sep 17 '22 13:09

Alex Wayne