Skip to content

Commit

Permalink
👍 Add isOmitOf
Browse files Browse the repository at this point in the history
  • Loading branch information
lambdalisue committed Feb 12, 2024
1 parent 5c74c1b commit f4df8e9
Show file tree
Hide file tree
Showing 4 changed files with 190 additions and 94 deletions.
134 changes: 67 additions & 67 deletions is/__snapshots__/factory_test.ts.snap
Original file line number Diff line number Diff line change
@@ -1,131 +1,143 @@
export const snapshot = {};

snapshot[`isInstanceOf<T> > returns properly named function 1`] = `"isInstanceOf(Date)"`;
snapshot[`isReadonlyUniformTupleOf<T> > returns properly named function 1`] = `"isReadonlyUniformTupleOf(3, isAny)"`;
snapshot[`isInstanceOf<T> > returns properly named function 2`] = `"isInstanceOf((anonymous))"`;
snapshot[`isReadonlyUniformTupleOf<T> > returns properly named function 2`] = `"isReadonlyUniformTupleOf(3, isNumber)"`;
snapshot[`isTupleOf<T, E> > returns properly named function 1`] = `
snapshot[`isReadonlyUniformTupleOf<T> > returns properly named function 3`] = `"isReadonlyUniformTupleOf(3, (anonymous))"`;
snapshot[`isRecordOf<T, K> > returns properly named function 1`] = `"isRecordOf(isNumber, isString)"`;
snapshot[`isRecordOf<T, K> > returns properly named function 2`] = `"isRecordOf((anonymous), isString)"`;
snapshot[`isSetOf<T> > returns properly named function 1`] = `"isSetOf(isNumber)"`;
snapshot[`isSetOf<T> > returns properly named function 2`] = `"isSetOf((anonymous))"`;
snapshot[`isTupleOf<T> > returns properly named function 1`] = `
"isTupleOf([
isNumber,
isString,
isBoolean
], isArray)"
])"
`;
snapshot[`isTupleOf<T, E> > returns properly named function 2`] = `"isTupleOf([(anonymous)], isArrayOf(isString))"`;
snapshot[`isTupleOf<T> > returns properly named function 2`] = `"isTupleOf([(anonymous)])"`;
snapshot[`isTupleOf<T, E> > returns properly named function 3`] = `
snapshot[`isTupleOf<T> > returns properly named function 3`] = `
"isTupleOf([
isTupleOf([
isTupleOf([
isNumber,
isString,
isBoolean
], isArray)
], isArray)
])
])
])"
`;
snapshot[`isRecordOf<T> > returns properly named function 1`] = `"isRecordOf(isNumber, undefined)"`;
snapshot[`isArrayOf<T> > returns properly named function 1`] = `"isArrayOf(isNumber)"`;
snapshot[`isRecordOf<T> > returns properly named function 2`] = `"isRecordOf((anonymous), undefined)"`;
snapshot[`isArrayOf<T> > returns properly named function 2`] = `"isArrayOf((anonymous))"`;
snapshot[`isSetOf<T> > returns properly named function 1`] = `"isSetOf(isNumber)"`;
snapshot[`isLiteralOf<T> > returns properly named function 1`] = `'isLiteralOf("hello")'`;
snapshot[`isSetOf<T> > returns properly named function 2`] = `"isSetOf((anonymous))"`;
snapshot[`isLiteralOf<T> > returns properly named function 2`] = `"isLiteralOf(100)"`;
snapshot[`isRecordOf<T, K> > returns properly named function 1`] = `"isRecordOf(isNumber, isString)"`;
snapshot[`isLiteralOf<T> > returns properly named function 3`] = `"isLiteralOf(100n)"`;
snapshot[`isRecordOf<T, K> > returns properly named function 2`] = `"isRecordOf((anonymous), isString)"`;
snapshot[`isLiteralOf<T> > returns properly named function 4`] = `"isLiteralOf(true)"`;
snapshot[`isLiteralOneOf<T> > returns properly named function 1`] = `'isLiteralOneOf(["hello", "world"])'`;
snapshot[`isLiteralOf<T> > returns properly named function 5`] = `"isLiteralOf(null)"`;
snapshot[`isReadonlyTupleOf<T> > returns properly named function 1`] = `
snapshot[`isLiteralOf<T> > returns properly named function 6`] = `"isLiteralOf(undefined)"`;
snapshot[`isLiteralOf<T> > returns properly named function 7`] = `"isLiteralOf(Symbol(asdf))"`;
snapshot[`isMapOf<T> > returns properly named function 1`] = `"isMapOf(isNumber, undefined)"`;
snapshot[`isMapOf<T> > returns properly named function 2`] = `"isMapOf((anonymous), undefined)"`;
snapshot[`isMapOf<T, K> > returns properly named function 1`] = `"isMapOf(isNumber, isString)"`;
snapshot[`isMapOf<T, K> > returns properly named function 2`] = `"isMapOf((anonymous), isString)"`;
snapshot[`isReadonlyTupleOf<T, E> > returns properly named function 1`] = `
"isReadonlyTupleOf([
isNumber,
isString,
isBoolean
])"
], isArray)"
`;
snapshot[`isReadonlyTupleOf<T> > returns properly named function 2`] = `"isReadonlyTupleOf([(anonymous)])"`;
snapshot[`isReadonlyTupleOf<T, E> > returns properly named function 2`] = `"isReadonlyTupleOf([(anonymous)], isArrayOf(isString))"`;
snapshot[`isReadonlyTupleOf<T> > returns properly named function 3`] = `
snapshot[`isReadonlyTupleOf<T, E> > returns properly named function 3`] = `
"isReadonlyTupleOf([
isReadonlyTupleOf([
isReadonlyTupleOf([
isNumber,
isString,
isBoolean
])
])
])"
], isArray)
], isArray)
], isArray)"
`;
snapshot[`isMapOf<T> > returns properly named function 1`] = `"isMapOf(isNumber, undefined)"`;
snapshot[`isUniformTupleOf<T> > returns properly named function 1`] = `"isUniformTupleOf(3, isAny)"`;
snapshot[`isMapOf<T> > returns properly named function 2`] = `"isMapOf((anonymous), undefined)"`;
snapshot[`isUniformTupleOf<T> > returns properly named function 2`] = `"isUniformTupleOf(3, isNumber)"`;
snapshot[`isTupleOf<T> > returns properly named function 1`] = `
snapshot[`isUniformTupleOf<T> > returns properly named function 3`] = `"isUniformTupleOf(3, (anonymous))"`;
snapshot[`isLiteralOneOf<T> > returns properly named function 1`] = `'isLiteralOneOf(["hello", "world"])'`;
snapshot[`isTupleOf<T, E> > returns properly named function 1`] = `
"isTupleOf([
isNumber,
isString,
isBoolean
])"
], isArray)"
`;
snapshot[`isTupleOf<T> > returns properly named function 2`] = `"isTupleOf([(anonymous)])"`;
snapshot[`isTupleOf<T, E> > returns properly named function 2`] = `"isTupleOf([(anonymous)], isArrayOf(isString))"`;
snapshot[`isTupleOf<T> > returns properly named function 3`] = `
snapshot[`isTupleOf<T, E> > returns properly named function 3`] = `
"isTupleOf([
isTupleOf([
isTupleOf([
isNumber,
isString,
isBoolean
])
])
], isArray)
], isArray)
])"
`;
snapshot[`isMapOf<T, K> > returns properly named function 1`] = `"isMapOf(isNumber, isString)"`;
snapshot[`isMapOf<T, K> > returns properly named function 2`] = `"isMapOf((anonymous), isString)"`;
snapshot[`isLiteralOf<T> > returns properly named function 1`] = `'isLiteralOf("hello")'`;
snapshot[`isLiteralOf<T> > returns properly named function 2`] = `"isLiteralOf(100)"`;
snapshot[`isLiteralOf<T> > returns properly named function 3`] = `"isLiteralOf(100n)"`;
snapshot[`isLiteralOf<T> > returns properly named function 4`] = `"isLiteralOf(true)"`;
snapshot[`isLiteralOf<T> > returns properly named function 5`] = `"isLiteralOf(null)"`;
snapshot[`isLiteralOf<T> > returns properly named function 6`] = `"isLiteralOf(undefined)"`;
snapshot[`isRecordOf<T> > returns properly named function 1`] = `"isRecordOf(isNumber, undefined)"`;
snapshot[`isLiteralOf<T> > returns properly named function 7`] = `"isLiteralOf(Symbol(asdf))"`;
snapshot[`isRecordOf<T> > returns properly named function 2`] = `"isRecordOf((anonymous), undefined)"`;
snapshot[`isReadonlyTupleOf<T, E> > returns properly named function 1`] = `
snapshot[`isReadonlyTupleOf<T> > returns properly named function 1`] = `
"isReadonlyTupleOf([
isNumber,
isString,
isBoolean
], isArray)"
])"
`;
snapshot[`isReadonlyTupleOf<T, E> > returns properly named function 2`] = `"isReadonlyTupleOf([(anonymous)], isArrayOf(isString))"`;
snapshot[`isReadonlyTupleOf<T> > returns properly named function 2`] = `"isReadonlyTupleOf([(anonymous)])"`;
snapshot[`isReadonlyTupleOf<T, E> > returns properly named function 3`] = `
snapshot[`isReadonlyTupleOf<T> > returns properly named function 3`] = `
"isReadonlyTupleOf([
isReadonlyTupleOf([
isReadonlyTupleOf([
isNumber,
isString,
isBoolean
], isArray)
], isArray)
], isArray)"
])
])
])"
`;
snapshot[`isObjectOf<T> > returns properly named function 1`] = `
Expand All @@ -146,18 +158,6 @@ snapshot[`isObjectOf<T> > returns properly named function 3`] = `
})"
`;
snapshot[`isUniformTupleOf<T> > returns properly named function 1`] = `"isUniformTupleOf(3, isAny)"`;
snapshot[`isUniformTupleOf<T> > returns properly named function 2`] = `"isUniformTupleOf(3, isNumber)"`;
snapshot[`isUniformTupleOf<T> > returns properly named function 3`] = `"isUniformTupleOf(3, (anonymous))"`;
snapshot[`isReadonlyUniformTupleOf<T> > returns properly named function 1`] = `"isReadonlyUniformTupleOf(3, isAny)"`;
snapshot[`isReadonlyUniformTupleOf<T> > returns properly named function 2`] = `"isReadonlyUniformTupleOf(3, isNumber)"`;
snapshot[`isReadonlyUniformTupleOf<T> > returns properly named function 3`] = `"isReadonlyUniformTupleOf(3, (anonymous))"`;
snapshot[`isArrayOf<T> > returns properly named function 1`] = `"isArrayOf(isNumber)"`;
snapshot[`isInstanceOf<T> > returns properly named function 1`] = `"isInstanceOf(Date)"`;
snapshot[`isArrayOf<T> > returns properly named function 2`] = `"isArrayOf((anonymous))"`;
snapshot[`isInstanceOf<T> > returns properly named function 2`] = `"isInstanceOf((anonymous))"`;
63 changes: 36 additions & 27 deletions is/__snapshots__/utility_test.ts.snap
Original file line number Diff line number Diff line change
@@ -1,35 +1,31 @@
export const snapshot = {};

snapshot[`isAllOf<T> > returns properly named function 1`] = `
"isAllOf([
isObjectOf({a: isNumber}),
isObjectOf({b: isString})
snapshot[`isOneOf<T> > returns properly named function 1`] = `
"isOneOf([
isNumber,
isString,
isBoolean
])"
`;
snapshot[`isPickOf<T, K> > returns properly named function 1`] = `
snapshot[`isOmitOf<T, K> > returns properly named function 1`] = `
"isObjectOf({
a: isNumber,
c: isBoolean
})"
`;
snapshot[`isPickOf<T, K> > returns properly named function 2`] = `"isObjectOf({a: isNumber})"`;
snapshot[`isOmitOf<T, K> > returns properly named function 2`] = `"isObjectOf({a: isNumber})"`;
snapshot[`isPartialOf<T> > returns properly named function 1`] = `
"isObjectOf({
a: isOptionalOf(isNumber),
b: isOptionalOf(isString),
c: isOptionalOf(isBoolean)
})"
`;
snapshot[`isOptionalOf<T> > returns properly named function 1`] = `"isOptionalOf(isNumber)"`;
snapshot[`isPartialOf<T> > returns properly named function 2`] = `
"isObjectOf({
a: isOptionalOf(isNumber),
b: isOptionalOf(isString),
c: isOptionalOf(isBoolean)
})"
snapshot[`isOptionalOf<T> > returns properly named function 2`] = `"isOptionalOf(isNumber)"`;
snapshot[`isAllOf<T> > returns properly named function 1`] = `
"isAllOf([
isObjectOf({a: isNumber}),
isObjectOf({b: isString})
])"
`;
snapshot[`isStrictOf<T> > returns properly named function 1`] = `
Expand All @@ -50,14 +46,27 @@ snapshot[`isStrictOf<T> > returns properly named function 3`] = `
}))"
`;
snapshot[`isOptionalOf<T> > returns properly named function 1`] = `"isOptionalOf(isNumber)"`;
snapshot[`isPartialOf<T> > returns properly named function 1`] = `
"isObjectOf({
a: isOptionalOf(isNumber),
b: isOptionalOf(isString),
c: isOptionalOf(isBoolean)
})"
`;
snapshot[`isOptionalOf<T> > returns properly named function 2`] = `"isOptionalOf(isNumber)"`;
snapshot[`isPartialOf<T> > returns properly named function 2`] = `
"isObjectOf({
a: isOptionalOf(isNumber),
b: isOptionalOf(isString),
c: isOptionalOf(isBoolean)
})"
`;
snapshot[`isOneOf<T> > returns properly named function 1`] = `
"isOneOf([
isNumber,
isString,
isBoolean
])"
snapshot[`isPickOf<T, K> > returns properly named function 1`] = `
"isObjectOf({
a: isNumber,
c: isBoolean
})"
`;
snapshot[`isPickOf<T, K> > returns properly named function 2`] = `"isObjectOf({a: isNumber})"`;
41 changes: 41 additions & 0 deletions is/utility.ts
Original file line number Diff line number Diff line change
Expand Up @@ -283,8 +283,49 @@ export function isPickOf<
& WithMetadata<IsObjectOfMetadata>;
}

/**
* Return a type predicate function that returns `true` if the type of `x` is `Omit<ObjectOf<T>, K>`.
*
* To enhance performance, users are advised to cache the return value of this function and mitigate the creation cost.
*
* ```typescript
* import { is } from "https://deno.land/x/unknownutil@$MODULE_VERSION/mod.ts";
*
* const isMyType = is.OmitOf(is.ObjectOf({
* a: is.Number,
* b: is.String,
* c: is.OptionalOf(is.Boolean),
* }), ["a", "c"]);
* const a: unknown = { a: 0, b: "a", other: "other" };
* if (isMyType(a)) {
* // The "a", "c", and "other" key in `a` is ignored.
* // 'a' is narrowed to { b: string }
* const _: { b: string } = a;
* }
* ```
*/
export function isOmitOf<
T extends Record<PropertyKey, unknown>,
K extends keyof T,
>(
pred: Predicate<T> & WithMetadata<IsObjectOfMetadata>,
keys: K[],
):
& Predicate<FlatType<Omit<T, K>>>
& WithMetadata<IsObjectOfMetadata> {
const s = new Set(keys);
const { args } = getPredicateMetadata(pred);
const predObj = Object.fromEntries(
Object.entries(args[0]).filter(([k]) => !s.has(k as K)),
);
return isObjectOf(predObj) as
& Predicate<FlatType<Omit<T, K>>>
& WithMetadata<IsObjectOfMetadata>;
}

export default {
AllOf: isAllOf,
OmitOf: isOmitOf,
OneOf: isOneOf,
OptionalOf: isOptionalOf,
PartialOf: isPartialOf,
Expand Down
Loading

0 comments on commit f4df8e9

Please sign in to comment.