Last active
March 28, 2022 15:28
-
-
Save xxzefgh/6552a646077c2f99844748a5fca23849 to your computer and use it in GitHub Desktop.
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
type MapFn<T> = (x: T) => unknown; | |
type MapSchema<T> = { [K in keyof T]?: MapFn<T[K]> | MapSchema<T[K]> }; | |
type MapReturnType<T, TMap extends MapSchema<T>> = { | |
[K in keyof T]: TMap[K] extends Function | |
? ReturnType<Extract<TMap[K], MapFn<T[K]>>> | |
: MapReturnType<T[K], TMap[K]>; | |
}; | |
function isMapFn<T = any>(x: unknown): x is MapFn<T> { | |
return typeof x === "function"; | |
} | |
function getKeys<T, K extends keyof T>(o: T): K[] { | |
return Object.keys(o) as any; | |
} | |
function mapProps<T, TMap extends MapSchema<T>>( | |
object: T, | |
mapSchema: TMap | |
): MapReturnType<T, TMap> { | |
const result: any = {}; | |
const keys = getKeys(object); | |
for (const key of keys) { | |
const value = object[key]; | |
let mappedValue: unknown; | |
if (mapSchema[key]) { | |
const fnOrSchema = mapSchema[key]; | |
if (isMapFn(fnOrSchema)) { | |
mappedValue = fnOrSchema(value); | |
} else { | |
mappedValue = mapProps(value, fnOrSchema); | |
} | |
} else { | |
mappedValue = value; | |
} | |
if (mappedValue !== undefined) { | |
result[key] = mappedValue; | |
} | |
} | |
return result; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment