@typedly/property
Version:
A TypeScript type definitions package to handle object property-related operations.
25 lines (24 loc) • 1.5 kB
TypeScript
/**
* @description Adds the property to the nested(deep) path, where the path is a string of dot-separated keys.
* If the path points to an existing object, it will continue the recursion to add the value at the next level.
* If the path points to a non-existent key, the type will create a new property at that location.
* This allows for deeply nested object manipulation at compile-time, providing a way to safely define nested properties.
* @export
* @template {object} Obj The type of the object to which the property should be added.
* @template {string} Path The path within the object, specified as a dot-separated string.
* @template Value The type of the value to be added at the specified path.
* @example
* type Example1 = DeepAdd<{ user: { name: string } }, 'user.age', number>;
* // type Example1 = { user: { name: string; } & { age: number; }; }
* type Example2 = DeepAdd<{ user: { address: { city: string } } }, 'user.address.zipcode', string>;
* // type Example2 = { user: { address: { city: string; } & { zipcode: string; }; }; }
*/
export type DeepAdd<Obj extends object, Path extends string, Value> = Path extends `${infer Key}.${infer Rest}` ? Key extends keyof Obj ? Obj[Key] extends object ? {
[K in keyof Obj]: K extends Key ? DeepAdd<Extract<Obj[K], object>, Rest, Value> : Obj[K];
} : {
[K in keyof Obj]: K extends Key ? DeepAdd<{}, Rest, Value> : Obj[K];
} : Obj & {
[K in Key]: DeepAdd<{}, Rest, Value>;
} : Obj & {
[K in Path]: Value;
};