Skip to content

Commit

Permalink
feat: create defuSchema
Browse files Browse the repository at this point in the history
Fixes unjs#48
  • Loading branch information
ferferga committed Aug 27, 2023
1 parent e0e2644 commit d54284a
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 2 deletions.
19 changes: 18 additions & 1 deletion src/defu.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import type { Merger, DefuFn as DefuFunction, DefuInstance } from "./types";
import type {
Merger,
DefuFn as DefuFunction,
DefuInstance,
DefuFnSchema,
} from "./types";

function isObject(value: any) {
return value !== null && typeof value === "object";
Expand Down Expand Up @@ -79,4 +84,16 @@ export const defuArrayFn = createDefu((object, key, currentValue) => {
}
});

// Custom version for skipping keys not present in defaults
export const defuSchema = createDefu((schema, key) => {
// Checking for hasOwnProperty is required for compatibility with older browsers
if (
!Object.hasOwn?.(schema, key) ||
!Object.prototype.hasOwnProperty.call(schema, key)
) {
return true;
}
return false;
}) as DefuFnSchema;

export type { Defu } from "./types";
18 changes: 18 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,24 @@ export type DefuFn = <
...defaults: Defaults
) => Defu<Source, Defaults>;

export type DefuFnSchema = <
Source extends Input,
Defaults extends Array<Input | IgnoredInput>
>(
source: Source,
...defaults: Defaults
) => Defaults extends [infer F, ...infer Rest]
? F extends Input
? Rest extends Array<Input | IgnoredInput>
? Defu<MergeObjects<F, F>, Rest>
: MergeObjects<F, F>
: F extends IgnoredInput
? Rest extends Array<Input | IgnoredInput>
? Defu<F, Rest>
: F
: F
: never;

export interface DefuInstance {
<Source extends Input, Defaults extends Array<Input | IgnoredInput>>(
source: Source | IgnoredInput,
Expand Down
21 changes: 20 additions & 1 deletion test/defu.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { expectTypeOf } from "expect-type";
import { it, describe, expect } from "vitest";
import { defu, createDefu, defuFn, defuArrayFn } from "../src/defu";
import { defu, createDefu, defuFn, defuArrayFn, defuSchema } from "../src/defu";

// Part of tests brought from jonschlinkert/defaults-deep (MIT)
const nonObject = [null, undefined, [], false, true, 123];
Expand All @@ -22,6 +22,25 @@ describe("defu", () => {
expectTypeOf(result2).toEqualTypeOf<{ a: string; d: string }>();
});

it("defuSchema(): should skip keys non present in default object", () => {
const result = defuSchema(
{ a: 1, b: 2, c: 3, d: 4 },
{ a: 2, c: 4, d: 6, e: 8 }
);
expect(result).toEqual({
a: 1,
c: 3,
d: 4,
e: 8,
});
expectTypeOf(result).toEqualTypeOf<{
a: number;
c: number;
d: number;
e: number;
}>();
});

it("should copy nested values", () => {
const result = defu({ a: { b: "c" } }, { a: { d: "e" } });
expect(result).toEqual({
Expand Down

0 comments on commit d54284a

Please sign in to comment.