object-assign-defined
Version:
A simple module that works exactly as Object.assign, but skips assigning undefined values.
36 lines (31 loc) • 1.2 kB
TypeScript
type NonUndefinedKeys<T> = {
[K in keyof T]-?: undefined extends T[K] ? never : K;
}[keyof T];
type DefinedProps<T> = Pick<T, NonUndefinedKeys<T>>;
type MergeDefined<
TTarget,
TSources extends readonly any[]
> = TSources extends readonly [infer H, ...infer R]
? MergeDefined<
TTarget & (H extends object ? DefinedProps<NonNullable<H>> : unknown),
R extends readonly any[] ? R : []
>
: TTarget;
/**
* Works like Object.assign, but skips properties whose value is `undefined` in the source objects.
* Mutates and returns the target object/array.
*
* Type behavior:
* - Only keys from sources whose value type does NOT include `undefined` are merged into the result type.
* - `null` sources are ignored.
* - Optional properties (which are `T[K] | undefined`) are excluded from the merged type.
*
* Example:
* objectAssignDefined({ a: 1 }, { b: 2 }, { c: undefined }) // => { a: 1, b: 2 }
* // type: { a: number } & { b: number } (no "c")
*/
declare function objectAssignDefined<
TTarget extends object,
const TSources extends readonly any[]
>(target: TTarget, ...sources: TSources): MergeDefined<TTarget, TSources>;
export = objectAssignDefined;