let say you want to convert number
types to undefined
given arbitrary object literal type, so here is how we do it
type a = { e: string; f: number; l: boolean }
type b = { e: string; f: number; l: boolean }
type c = { e: string; f: number; l: { e: string; f: number; l: boolean } }
type ABC = { a: a; b: b; c: c }
type ConvertNumberToUndefined<T extends Record<string, unknown>> = {
[K in keyof T]: T[K] extends Record<string, unknown>
? ConvertNumberToUndefined<T[K]>
: T[K] extends number
? undefined
: T[K]
}
type newABC = ConvertNumberToUndefined<ABC>
type a_f = newABC['a']['f'] // undefined
// ^?
type b_f = newABC['b']['f'] // undefined
// ^?
type c_f = newABC['c']['l']['f'] // undefined
// ^?
now let say we want to keep type b
intact, we don't want to change anything, that is when interface come in handy
type a = { e: string; f: number; l: boolean }
interface b { e: string; f: number; l: boolean }
type c = { e: string; f: number; l: { e: string; f: number; l: boolean } }
type ABC = { a: a; b: b; c: c }
type ConvertNumberToUndefined<T extends Record<string, unknown>> = {
[K in keyof T]: T[K] extends Record<string, unknown>
? ConvertNumberToUndefined<T[K]>
: T[K] extends number
? undefined
: T[K]
}
type newABC = ConvertNumberToUndefined<ABC>
type a_f = newABC['a']['f'] // undefined
// ^?
type b_f = newABC['b']['f'] // number
// ^?
type c_f = newABC['c']['l']['f'] // undefined
// ^?
just convert b
to interface and we are done
this is useful when we are dealing with data type that has special meaning, for example Date and Geopoint
Top comments (0)