I want to write a type utility that omits fields recursively.
Something that you would name and use like that OmitRecursively<SomeType, 'keyToOmit'>
I've tried to do it using mapped types + conditional typing but I stuck on the case when all required fields got typed correctly (hence field disappeared from nested type), but optional fields are ignored with that approach.
// This is for one function that removes recursively __typename field
// that Appolo client adds
type Deapolify<T extends { __typename: string }> = Omit<
{ [P in keyof T]: T[P] extends { __typename: string } ? Deapolify<T[P]> : T[P] },
'__typename'
>
// Or more generic attempt
type OmitRecursively<T extends any, K extends keyof T> = Omit<
{ [P in keyof T]: T[P] extends any ? Omit<T[P], K> : never },
K
>
Expected behavior would be root and all nested keys that have a type with a key that should be recursively omitted is omitted. E.g
type A = {
keyToKeep: string
keyToOmit: string
nested: {
keyToKeep: string
keyToOmit: string
}
nestedOptional?: {
keyToKeep: string
keyToOmit: string
}
}
type Result = OmitRecursively<A, 'keyToOmit'>
type Expected = {
keyToKeep: string
nested: {
keyToKeep: string
}
nestedOptional?: {
keyToKeep: string
}
}
Expected === Result