I'm pretty sure its my lack of experience utilizing complex generics so I'm hoping someone has ideas on how to accomplish this. My use case is for creating "form types" for my React/Formik form values without having to either re-type a new definition or pass in full objects with lots of non-updatable properties.
I found this answer which shows how to exclude readonly properties from a TypeScript type, but I'm finding it hard to wrap my brain around making it recursive. Additionally, I'd love to have it omit properties that return empty nested objects (if possible).
How to exclude getter only properties from type in typescript
type IfEquals<X, Y, A=X, B=never> =
(<T>() => T extends X ? 1 : 2) extends
(<T>() => T extends Y ? 1 : 2) ? A : B;
type WritableKeys<T> = {
[P in keyof T]-?: IfEquals<{ [Q in P]: T[P] }, { -readonly [Q in P]: T[P] }, P>
}[keyof T];
type ReadonlyKeys<T> = {
[P in keyof T]-?: IfEquals<{ [Q in P]: T[P] }, { -readonly [Q in P]: T[P] }, never, P>
}[keyof T];
type Writable<T> = Pick<T, WritableKeys<T>>
type Brand = {
readonly id: number;
name: string;
logo: {
readonly id: number;
url: string;
},
creator: {
readonly id: number;
}
};
type EditableBrand = Writable<Brand>;
// type EditableBrand = {
// name: string;
// logo: {
// url: string;
// }
// };