tiny-merge-patch
Version:
JSON Merge Patch (RFC 7396) Implementation
24 lines (23 loc) • 1.19 kB
TypeScript
/**
* Extract keys from a patch object where the value is null (properties to remove).
*/
type NullKeys<T> = {
[K in keyof T]: T[K] extends null ? K : never;
}[keyof T];
type IsPlainObject<T> = T extends readonly unknown[] ? false : T extends Record<PropertyKey, unknown> ? true : false;
declare const emptyObjectSymbol: unique symbol;
export interface EmptyObject {
[emptyObjectSymbol]?: never;
}
type NormalizeEmptyObject<T extends object> = keyof T extends never ? EmptyObject : T;
type Patched<Origin, Patch> = IsPlainObject<Patch> extends true ? IsPlainObject<Origin> extends true ? NormalizeEmptyObject<{
[K in Exclude<keyof Origin | keyof Patch, NullKeys<Patch>>]: K extends keyof Patch ? K extends keyof Origin ? Patched<Origin[K], Patch[K]> : Patched<unknown, Patch[K]> : K extends keyof Origin ? Origin[K] : never;
}> : NormalizeEmptyObject<{
[K in Exclude<keyof Patch, NullKeys<Patch>>]: Patched<unknown, Patch[K]>;
}> : Patch;
/**
* Apply a JSON merge patch. The origin is not modified, but unchanged
* properties are recycled.
*/
export declare function apply<Origin, Patch>(origin: Origin, patch: Patch): Patched<Origin, Patch>;
export default apply;