Last active
July 31, 2019 21:06
-
-
Save fvilante/60db584c117a4371ef1369a65ce6004d to your computer and use it in GitHub Desktop.
Utility type to introspect an interface
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Author: Flavio | |
type __PairList<T> = { | |
[Key in keyof T]: { | |
readonly key: Key | |
readonly value: T[Key] | |
} | |
} | |
type __Pair<T> = __PairList<T>[keyof T] | |
type AnyPair = __Pair<any> | |
// -------------------------- | |
// utils - interface Parser | |
// -------------------------- | |
type TKey = string | number | symbol | |
/** Final operations over a Pair */ | |
type __GetKeys<T extends {readonly key: any}> = T['key'] | |
type __GetValue<T extends {readonly value: any}> = T['value'] | |
/** Result is a Pair */ | |
type __FilterKeysByValue<T, Value extends T[keyof T]> = Extract<__Pair<T>, {readonly value: Value}> | |
type GetKeys<T> = __GetKeys<__Pair<T>> | |
type GetValues<T> = __GetValue<__Pair<T>> | |
type FilterKeysByValue<T, Value extends T[keyof T]> = __GetKeys<__FilterKeysByValue<T, Value>> | |
// ======================================== | |
// informal test | |
// ======================================== | |
const Test01 = { | |
// space | |
'milimeter': 'Space', | |
'meter': 'Space', | |
// time | |
'second': 'Time', | |
'minute': 'Time', | |
} as const | |
type Test01 = typeof Test01 | |
// put cursor over types bellow to see type inference result (use vscode with Typescript Plugin) | |
type Get_Keys = GetKeys<Test01> // OK "milimeter" | "meter" | "second" | "minute" | |
type Get_Values = GetValues<Test01> // OK "Space" | "Time" | |
type Get_Only_Space = FilterKeysByValue<Test01,'Space'> // OK "milimeter" | "meter" | |
// --------- | |
// Test 02 | |
// --------- | |
const Test02 = { | |
// space | |
'milimeter': {name: 'Oi', number: 10}, | |
'meter': 'Space', | |
// time | |
'second': 'Time', | |
'minute': {name: 'Oi', number: 20}, | |
} as const | |
type Test02 = typeof Test02 | |
type _PairList = __PairList<Test02> // OK | |
type _Get_Keys = GetKeys<Test02> // OK "milimeter" | "meter" | "second" | "minute" | |
type _Get_Values = GetValues<Test02> // OK | |
type _Get_Only_Space = FilterKeysByValue<Test02, { | |
readonly name: "Oi"; | |
readonly number: 10; | |
}> // // OK "milimeter" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment