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?
CodePudding user response:
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.