Skip to content

Instantly share code, notes, and snippets.

@jsdevtom
Last active August 30, 2019 04:34
Show Gist options
  • Save jsdevtom/24f41f43e40857986c8313816cb9302b to your computer and use it in GitHub Desktop.
Save jsdevtom/24f41f43e40857986c8313816cb9302b to your computer and use it in GitHub Desktop.
Recursifies an object on to another object in Typescript
/**
* T: The normal object to apply O to at every nested object
*
* @example
export const OBJECT_ID = Symbol('_objectId');
export interface IHasOBJECT_ID {
[OBJECT_ID]: UUID;
}
interface John {
john: {
name: string,
address: {
num: number,
street: string,
town: {
name: string,
population: number,
},
},
},
}
const john: RecursifyOnto<John, IHasOBJECT_ID> = {
john: {
name: 'john',
address: {
town: {
name: 'hi',
population: 5,
[OBJECT_ID]: 'id',
},
num: 1,
street: 'A street',
[OBJECT_ID]: 'id',
},
[OBJECT_ID]: 'id',
},
[OBJECT_ID]: 'id',
};
*/
export type RecursifyOnto<T, O> = {
[P in keyof T]: T[P] extends string ? T[P] :
T[P] extends number ? T[P] :
T[P] extends boolean ? T[P] :
T[P] extends undefined ? T[P] :
T[P] extends Function ? T[P] :
RecursifyOnto<T[P], O> & O
} & (T extends string ? T :
T extends number ? T :
T extends boolean ? T :
T extends undefined ? T :
T extends Function ? T :
O);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment