Every of our database tables has an identifier (id) and version. Which means every concrete Entity extends from the Entity interface in order to have those two attributes.
interface Entity {
id: number;
version: number;
}
Here is a multi-level entity for example purposes.
interface Address extends Entity {
street: string;
hno: string;
zip: string;
city: string;
country: string;
}
interface Department extends Entity {
name: string;
}
interface User extends Entity {
name: string;
birthday: string;
address: Address;
department: Department;
}
Now I want a generic type which replaces all appearances of id and version (even the fields in the sub-objects) into optional. Which means from
User {
dbid: number;
version: number;
name: string;
birthday: string;
address: {
dbid: number;
version: number;
street: string;
hno: string;
zip: string;
city: string;
country: string;
};
department: {
dbid: number;
version: number;
name: string;
};
}
into
User {
dbid?: number;
version?: number;
name: string;
birthday: string;
address: {
dbid?: number;
version?: number;
street: string;
hno: string;
zip: string;
city: string;
country: string;
};
department: {
dbid?: number;
version?: number;
name: string;
};
}
As I said as a generic type, because I have a lot of different entities where I want to perform the same.
Something like
export type NewEntity<T extends Entity> = {
// remove id and version fields
[K in keyof Omit<T, 'dbid' | 'version'>]: T[K] extends Entity ? NewEntity<T[K]> : T[K];
};
but this removes only the two attributes but lacks the redefinition of
id?: number;
version?: number