Skip to content

Commit b9ec2c0

Browse files
committed
feat[isOmitOf]: copy symbol properties from pred.predObj
1 parent 093cdbe commit b9ec2c0

File tree

3 files changed

+67
-5
lines changed

3 files changed

+67
-5
lines changed

is/__snapshots__/omit_of_test.ts.snap

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,12 @@ snapshot[`isOmitOf<T, K> > returns properly named predicate function 1`] = `
88
`;
99

1010
snapshot[`isOmitOf<T, K> > returns properly named predicate function 2`] = `"isObjectOf({a: isNumber})"`;
11+
12+
snapshot[`isOmitOf<T, K> > with symbol properties > returns properly named predicate function 1`] = `
13+
"isObjectOf({
14+
a: isNumber,
15+
Symbol(c): isBoolean
16+
})"
17+
`;
18+
19+
snapshot[`isOmitOf<T, K> > with symbol properties > returns properly named predicate function 2`] = `"isObjectOf({a: isNumber})"`;

is/omit_of.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,11 @@ export function isOmitOf<
4343
):
4444
& Predicate<FlatType<Omit<T, K>>>
4545
& IsPredObj<P> {
46-
const s = new Set(keys);
47-
const predObj = Object.fromEntries(
48-
Object.entries(pred.predObj).filter(([k]) => !s.has(k as K)),
49-
);
50-
return isObjectOf(predObj) as
46+
const predObj = { ...pred.predObj };
47+
for (const key of keys) {
48+
delete predObj[key];
49+
}
50+
return isObjectOf(predObj as Record<PropertyKey, Predicate<unknown>>) as
5151
& Predicate<FlatType<Omit<T, K>>>
5252
& IsPredObj<P>;
5353
}

is/omit_of_test.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,57 @@ Deno.test("isOmitOf<T, K>", async (t) => {
5454
>(true);
5555
}
5656
});
57+
58+
await t.step("with symbol properties", async (t) => {
59+
const b = Symbol("b");
60+
const c = Symbol("c");
61+
const pred = is.ObjectOf({
62+
a: is.Number,
63+
[b]: is.String,
64+
[c]: is.Boolean,
65+
});
66+
67+
await t.step("returns properly named predicate function", async (t) => {
68+
assertEquals(typeof isOmitOf(pred, [b]), "function");
69+
await assertSnapshot(t, isOmitOf(pred, [b]).name);
70+
await assertSnapshot(t, isOmitOf(isOmitOf(pred, [b]), [c]).name);
71+
});
72+
73+
await t.step("returns true on Omit<T, K> object", () => {
74+
assertEquals(
75+
isOmitOf(pred, [b])({ a: 0, [b]: undefined, [c]: true }),
76+
true,
77+
);
78+
assertEquals(isOmitOf(pred, [b, c])({ a: 0 }), true);
79+
});
80+
81+
await t.step("returns false on non Omit<T, K> object", () => {
82+
assertEquals(
83+
isOmitOf(pred, [b])("a"),
84+
false,
85+
"Value is not an object",
86+
);
87+
assertEquals(
88+
isOmitOf(pred, [b])({ a: 0, [b]: "a", [c]: "" }),
89+
false,
90+
"Object have a different type property",
91+
);
92+
});
93+
94+
await t.step("predicated type is correct", () => {
95+
const x: unknown = { a: 0, [b]: "a", [c]: true };
96+
97+
if (isOmitOf(pred, [b])(x)) {
98+
assertType<
99+
Equal<typeof x, { a: number; [c]: boolean }>
100+
>(true);
101+
}
102+
103+
if (isOmitOf(isOmitOf(pred, [b]), [c])(x)) {
104+
assertType<
105+
Equal<typeof x, { a: number }>
106+
>(true);
107+
}
108+
});
109+
});
57110
});

0 commit comments

Comments
 (0)