deep-guards 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -58,8 +58,9 @@ if (vehicleGuard(value)) {
58
58
  1. [isAnyArray](#isanyarray)
59
59
  2. [isAnyRecord](#isanyrecord)
60
60
  3. [isArrayOf](#isarrayof)
61
- 4. [isRecordOf](#isrecordof)
62
- 5. [isObjectOf](#isobjectof)
61
+ 4. [isTupleOf](#istupleof)
62
+ 5. [isRecordOf](#isrecordof)
63
+ 6. [isObjectOf](#isobjectof)
63
64
  4. [Macros](#macros)
64
65
  1. [isDiscriminatedObjectOf](#isdiscriminatedobjectof)
65
66
  5. [guardOrThrow](#guardorthrow)
@@ -160,6 +161,21 @@ Higher order guard. This will pass if the incoming value is an array which conta
160
161
 
161
162
  NOTE: This passes for empty arrays
162
163
 
164
+ ### isTupleOf
165
+
166
+ Higher order guard. This takes in any number of guards, and then checks that the incoming value is an array of the same size, with the guards guarding the items in the same order as they appear.
167
+
168
+ For example:
169
+
170
+ ```ts
171
+ const myTupleGuard = isTupleOf(isNumber, isString, isBoolean);
172
+ const value: unknown = [1, "foo", true];
173
+
174
+ if (myTupleGuard(value)) {
175
+ // value passes
176
+ }
177
+ ```
178
+
163
179
  ### isRecordOf
164
180
 
165
181
  Higher order guard. It has two guard parameters, where the first is the key guard, and then the second is a value guard which is optional. If you don't pass in a value guard, the returned guard function has `unknown`s as the value type.
@@ -1,8 +1,14 @@
1
- import { Guard, GuardSchemaOf } from "./types.js";
1
+ import { Guard, GuardSchemaOf } from "./types";
2
2
  export declare function isOptional<T>(guard: Guard<T>): Guard<T | undefined>;
3
3
  export declare function isNullable<T>(guard: Guard<T>): Guard<T | null | undefined>;
4
4
  export declare function isNonNullable<T>(value: T | null | undefined): value is T;
5
5
  export declare function isNot<const N>(guard: Guard<N>): <const T>(value: T | N) => value is T;
6
6
  export declare function isOneOf<const T extends (string | number | boolean | symbol | null | undefined)[]>(...values: T): Guard<(typeof values)[number]>;
7
7
  export declare function isUnionOf<T extends readonly unknown[]>(...guards: GuardSchemaOf<T>): Guard<T[number]>;
8
+ type ArrayToIntersection<A extends readonly unknown[]> = A extends [
9
+ infer T,
10
+ ...infer R
11
+ ] ? T & ArrayToIntersection<R> : unknown;
12
+ export declare function isIntersectionOf<T extends readonly unknown[]>(...guards: GuardSchemaOf<T>): Guard<ArrayToIntersection<T>>;
8
13
  export declare function isExact<const T>(expected: T, deep?: boolean): Guard<T>;
14
+ export {};
package/dist/compound.js CHANGED
@@ -2,7 +2,7 @@ export function isOptional(guard) {
2
2
  if (typeof guard !== "function") {
3
3
  throw new TypeError(`isOptional expects a guard parameter. Got instead: ${guard}`);
4
4
  }
5
- return ((value) => value === undefined || guard(value));
5
+ return (value) => value === undefined || guard(value);
6
6
  }
7
7
  export function isNullable(guard) {
8
8
  if (typeof guard !== "function") {
@@ -29,6 +29,12 @@ export function isUnionOf(...guards) {
29
29
  }
30
30
  return (value) => guards.some((guard) => guard(value));
31
31
  }
32
+ export function isIntersectionOf(...guards) {
33
+ if (guards.every((guard) => typeof guard !== "function")) {
34
+ throw new TypeError(`isIntersectionOf expects N guard parameters. Got instead: ${guards}`);
35
+ }
36
+ return (value) => guards.every((guard) => guard(value));
37
+ }
32
38
  function isEqual(a, b) {
33
39
  return (a === b ||
34
40
  (a != null &&
@@ -1 +1 @@
1
- {"version":3,"file":"compound.js","sourceRoot":"src/","sources":["compound.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"compound.js","sourceRoot":"src/","sources":["compound.ts"],"names":[],"mappings":"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"}
package/dist/errors.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Guard } from "./types.js";
1
+ import { Guard } from "./types";
2
2
  export declare class GuardError extends Error {
3
3
  name: string;
4
4
  }
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
- export * from "./compound.js";
2
- export * from "./errors.js";
3
- export * from "./primitives.js";
4
- export * from "./structures.js";
5
- export * from "./types.js";
1
+ export * from "./compound";
2
+ export * from "./errors";
3
+ export * from "./macros";
4
+ export * from "./primitives";
5
+ export * from "./structures";
6
+ export * from "./types";
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
- export * from "./compound.js";
2
- export * from "./errors.js";
3
- export * from "./primitives.js";
4
- export * from "./structures.js";
5
- export * from "./types.js";
1
+ export * from "./compound";
2
+ export * from "./errors";
3
+ export * from "./macros";
4
+ export * from "./primitives";
5
+ export * from "./structures";
6
+ export * from "./types";
6
7
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"src/","sources":["index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"src/","sources":["index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { Guard } from "./types";
2
+ export declare const isDiscriminatedObjectOf: <T extends string, O extends object>(type: T, guard: Guard<O>) => Guard<{
3
+ type: T;
4
+ } & O>;
package/dist/macros.js ADDED
@@ -0,0 +1,4 @@
1
+ import { isExact, isIntersectionOf } from "./compound";
2
+ import { isObjectOf } from "./structures";
3
+ export const isDiscriminatedObjectOf = (type, guard) => isIntersectionOf(isObjectOf({ type: isExact(type) }), guard);
4
+ //# sourceMappingURL=macros.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"macros.js","sourceRoot":"src/","sources":["macros.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG1C,MAAM,CAAC,MAAM,uBAAuB,GAAG,CACrC,IAAO,EACP,KAAe,EACS,EAAE,CAC1B,gBAAgB,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,KAAK,CAE1D,CAAC"}
@@ -1,4 +1,4 @@
1
- import { Guard } from "./types.js";
1
+ import { Guard } from "./types";
2
2
  export declare const isUnknown: Guard<unknown>;
3
3
  export declare const isNull: Guard<null>;
4
4
  export declare const isUndefined: Guard<undefined>;
@@ -1,9 +1,10 @@
1
- import { Guard, GuardSchemaOf } from "./types.js";
1
+ import { Guard, GuardSchemaOf } from "./types";
2
2
  type ObjectKey = string | number | symbol;
3
3
  export declare const isAnyArray: Guard<unknown[]>;
4
4
  export declare const isAnyRecord: Guard<Record<ObjectKey, unknown>>;
5
5
  export declare function isArrayOf<T>(guard: Guard<T>): Guard<T[]>;
6
+ export declare function isTupleOf<T extends readonly unknown[]>(...tupleGuards: GuardSchemaOf<T>): Guard<T>;
6
7
  export declare function isRecordOf<K extends ObjectKey>(keyGuard: Guard<K>): Guard<Record<K, unknown>>;
7
8
  export declare function isRecordOf<K extends ObjectKey, V>(keyGuard: Guard<K>, valueGuard: Guard<V>): Guard<Record<K, V>>;
8
- export declare function isObjectOf<O extends object>(schema: GuardSchemaOf<O>): O extends unknown[] ? never : Guard<O>;
9
+ export declare function isObjectOf<O extends object>(schema: GuardSchemaOf<O>): O extends unknown[] ? never : {} extends O ? never : Guard<O>;
9
10
  export {};
@@ -9,6 +9,14 @@ export function isArrayOf(guard) {
9
9
  }
10
10
  return (value) => Array.isArray(value) && value.every(guard);
11
11
  }
12
+ export function isTupleOf(...tupleGuards) {
13
+ if (tupleGuards.some((guard) => typeof guard !== "function")) {
14
+ throw new TypeError(`isTupleOf expects guard parameters. Got instead: ${JSON.stringify(tupleGuards)}`);
15
+ }
16
+ return (value) => Array.isArray(value) &&
17
+ value.length === tupleGuards.length &&
18
+ tupleGuards.every((guard, i) => guard(value[i]));
19
+ }
12
20
  export function isRecordOf(keyGuard, valueGuard) {
13
21
  if (typeof keyGuard !== "function") {
14
22
  throw new TypeError(`isRecordOf keyGuard expects a guard parameter. Got instead: ${keyGuard}`);
@@ -22,16 +30,16 @@ export function isRecordOf(keyGuard, valueGuard) {
22
30
  objectKeys(value).every((key) => keyGuard(key) && (valueGuard?.(value[key]) ?? true));
23
31
  }
24
32
  export function isObjectOf(schema) {
33
+ if (schema == null || typeof schema !== "object") {
34
+ throw new TypeError(`isObjectOf expects a guard schema object. Got instead: ${schema}`);
35
+ }
25
36
  const schemaKeys = objectKeys(schema);
26
- const schemaUnknown = schema;
27
- if (schemaKeys.length === 0) {
28
- throw new Error("isObjectOf received an empty schema");
37
+ if (Array.isArray(schema) ||
38
+ schemaKeys.some((key) => typeof schema[key] !== "function")) {
39
+ throw new TypeError(`isObjectOf expects a guard schema object. Got instead ${JSON.stringify(schema)}`);
29
40
  }
30
- else if (schemaUnknown == null ||
31
- typeof schemaUnknown !== "object" ||
32
- Array.isArray(schemaUnknown) ||
33
- schemaKeys.some((key) => typeof schemaUnknown[key] !== "function")) {
34
- throw new TypeError(`isObjectOf expects a guard schema. Got instead: ${schemaUnknown}`);
41
+ else if (schemaKeys.length === 0) {
42
+ throw new Error("isObjectOf received an empty schema");
35
43
  }
36
44
  return ((value) => value != null &&
37
45
  typeof value === "object" &&
@@ -1 +1 @@
1
- {"version":3,"file":"structures.js","sourceRoot":"src/","sources":["structures.ts"],"names":[],"mappings":"AAIA,SAAS,UAAU,CAAsB,GAAuB;IAC9D,OAAQ,MAAM,CAAC,mBAAmB,CAAC,GAAG,CAAS,CAAC,MAAM,CACpD,MAAM,CAAC,qBAAqB,CAAC,GAAG,CAAQ,CACzC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,UAAU,GAAqB,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAE5E,MAAM,CAAC,MAAM,WAAW,GAAsC,CAC5D,KAAK,EACgC,EAAE,CACvC,KAAK,IAAI,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAEtE,MAAM,UAAU,SAAS,CAAI,KAAe;IAC1C,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE,CAAC;QAChC,MAAM,IAAI,SAAS,CACjB,qDAAqD,KAAK,EAAE,CAC7D,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,KAAK,EAAgB,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AAC7E,CAAC;AASD,MAAM,UAAU,UAAU,CACxB,QAAkB,EAClB,UAAqB;IAErB,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;QACnC,MAAM,IAAI,SAAS,CACjB,+DAA+D,QAAQ,EAAE,CAC1E,CAAC;IACJ,CAAC;SAAM,IAAI,UAAU,IAAI,IAAI,IAAI,OAAO,UAAU,KAAK,UAAU,EAAE,CAAC;QAClE,MAAM,IAAI,SAAS,CACjB,2EAA2E,UAAU,EAAE,CACxF,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,KAAK,EAAyB,EAAE,CACtC,KAAK,IAAI,IAAI;QACb,OAAO,KAAK,KAAK,QAAQ;QACzB,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACrB,UAAU,CAAC,KAAK,CAAC,CAAC,KAAK,CACrB,CAAC,GAAG,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAC7D,CAAC;AACN,CAAC;AAED,MAAM,UAAU,UAAU,CACxB,MAAwB;IAExB,MAAM,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;IACtC,MAAM,aAAa,GAAG,MAAiB,CAAC;IACxC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IACzD,CAAC;SAAM,IACL,aAAa,IAAI,IAAI;QACrB,OAAO,aAAa,KAAK,QAAQ;QACjC,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC;QAC5B,UAAU,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAQ,aAAmB,CAAC,GAAG,CAAC,KAAK,UAAU,CAAC,EACzE,CAAC;QACD,MAAM,IAAI,SAAS,CACjB,mDAAmD,aAAa,EAAE,CACnE,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,CAAC,KAAK,EAAc,EAAE,CAC5B,KAAK,IAAI,IAAI;QACb,OAAO,KAAK,KAAK,QAAQ;QACzB,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACrB,UAAU,CAAC,KAAK,CACd,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,IAAI,KAAK,IAAI,MAAM,CAAC,GAAG,CAAC,CAAE,KAAW,CAAC,GAAG,CAAC,CAAC,CACxD,CAA2C,CAAC;AACjD,CAAC"}
1
+ {"version":3,"file":"structures.js","sourceRoot":"src/","sources":["structures.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -8,7 +8,7 @@
8
8
  "type": "module",
9
9
  "types": "dist/index.d.ts",
10
10
  "homepage": "https://github.com/eniallator/Deep-Guards",
11
- "version": "1.0.2",
11
+ "version": "1.0.3",
12
12
  "scripts": {
13
13
  "test": "jest",
14
14
  "build": "tsc",
@@ -28,15 +28,15 @@
28
28
  "@types/eslint": "^9.6.1",
29
29
  "@types/eslint__js": "^8.42.3",
30
30
  "@types/jest": "^29.5.14",
31
- "@typescript-eslint/eslint-plugin": "^8.15.0",
32
- "@typescript-eslint/parser": "^8.15.0",
31
+ "@typescript-eslint/eslint-plugin": "^8.16.0",
32
+ "@typescript-eslint/parser": "^8.16.0",
33
33
  "babel-jest": "^29.7.0",
34
34
  "eslint": "^9.15.0",
35
35
  "eslint-plugin-eslint-comments": "^3.2.0",
36
36
  "eslint-plugin-import": "^2.31.0",
37
37
  "eslint-plugin-jest": "^28.9.0",
38
38
  "jest": "^29.7.0",
39
- "typescript": "^5.6.3",
40
- "typescript-eslint": "^8.15.0"
39
+ "typescript": "^5.7.2",
40
+ "typescript-eslint": "^8.16.0"
41
41
  }
42
42
  }
package/src/compound.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Guard, GuardSchemaOf } from "./types.js";
1
+ import { Guard, GuardSchemaOf } from "./types";
2
2
 
3
3
  export function isOptional<T>(guard: Guard<T>): Guard<T | undefined> {
4
4
  if (typeof guard !== "function") {
@@ -7,9 +7,7 @@ export function isOptional<T>(guard: Guard<T>): Guard<T | undefined> {
7
7
  );
8
8
  }
9
9
 
10
- return ((value) => value === undefined || guard(value)) as Guard<
11
- T | undefined
12
- >;
10
+ return (value): value is T | undefined => value === undefined || guard(value);
13
11
  }
14
12
 
15
13
  export function isNullable<T>(guard: Guard<T>): Guard<T | null | undefined> {
package/src/errors.ts CHANGED
@@ -1,17 +1,17 @@
1
- import { Guard } from "./types.js";
2
-
3
- export class GuardError extends Error {
4
- name = "GuardError";
5
- }
6
-
7
- export function guardOrThrow<T>(
8
- value: unknown,
9
- guard: Guard<T>,
10
- hint?: string
11
- ): T {
12
- if (guard(value)) {
13
- return value;
14
- } else {
15
- throw new GuardError(hint ?? "Guard error");
16
- }
17
- }
1
+ import { Guard } from "./types";
2
+
3
+ export class GuardError extends Error {
4
+ name = "GuardError";
5
+ }
6
+
7
+ export function guardOrThrow<T>(
8
+ value: unknown,
9
+ guard: Guard<T>,
10
+ hint?: string
11
+ ): T {
12
+ if (guard(value)) {
13
+ return value;
14
+ } else {
15
+ throw new GuardError(hint ?? "Guard error");
16
+ }
17
+ }
package/src/index.ts CHANGED
@@ -1,5 +1,6 @@
1
- export * from "./compound.js";
2
- export * from "./errors.js";
3
- export * from "./primitives.js";
4
- export * from "./structures.js";
5
- export * from "./types.js";
1
+ export * from "./compound";
2
+ export * from "./errors";
3
+ export * from "./macros";
4
+ export * from "./primitives";
5
+ export * from "./structures";
6
+ export * from "./types";
package/src/macros.ts CHANGED
@@ -6,6 +6,6 @@ export const isDiscriminatedObjectOf = <T extends string, O extends object>(
6
6
  type: T,
7
7
  guard: Guard<O>
8
8
  ): Guard<{ type: T } & O> =>
9
- isIntersectionOf(isObjectOf({ type: isExact(type) }), guard) as Guard<
9
+ isIntersectionOf(isObjectOf({ type: isExact(type) }), guard) satisfies Guard<
10
10
  { type: T } & O
11
11
  >;
package/src/primitives.ts CHANGED
@@ -1,23 +1,23 @@
1
- import { Guard } from "./types.js";
2
-
3
- export const isUnknown: Guard<unknown> = (_value): _value is unknown => true;
4
-
5
- export const isNull: Guard<null> = (value) => value === null;
6
-
7
- export const isUndefined: Guard<undefined> = (value) => value === undefined;
8
-
9
- export const isNumber: Guard<number> = (value) => typeof value === "number";
10
-
11
- export const isInteger: Guard<number> = (value): value is number =>
12
- Number.isInteger(value);
13
-
14
- export const isString: Guard<string> = (value) => typeof value === "string";
15
-
16
- export const isSymbol: Guard<symbol> = (value) => typeof value === "symbol";
17
-
18
- export const isBoolean: Guard<boolean> = (value) =>
19
- value === true || value === false;
20
-
21
- export const isFunction: Guard<(...args: unknown[]) => unknown> = (
22
- value
23
- ): value is (...args: unknown[]) => unknown => typeof value === "function";
1
+ import { Guard } from "./types";
2
+
3
+ export const isUnknown: Guard<unknown> = (_value): _value is unknown => true;
4
+
5
+ export const isNull: Guard<null> = (value) => value === null;
6
+
7
+ export const isUndefined: Guard<undefined> = (value) => value === undefined;
8
+
9
+ export const isNumber: Guard<number> = (value) => typeof value === "number";
10
+
11
+ export const isInteger: Guard<number> = (value): value is number =>
12
+ Number.isInteger(value);
13
+
14
+ export const isString: Guard<string> = (value) => typeof value === "string";
15
+
16
+ export const isSymbol: Guard<symbol> = (value) => typeof value === "symbol";
17
+
18
+ export const isBoolean: Guard<boolean> = (value) =>
19
+ value === true || value === false;
20
+
21
+ export const isFunction: Guard<(...args: unknown[]) => unknown> = (
22
+ value
23
+ ): value is (...args: unknown[]) => unknown => typeof value === "function";
package/src/structures.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Guard, GuardSchemaOf } from "./types.js";
1
+ import { Guard, GuardSchemaOf } from "./types";
2
2
 
3
3
  type ObjectKey = string | number | symbol;
4
4
 
@@ -25,6 +25,23 @@ export function isArrayOf<T>(guard: Guard<T>): Guard<T[]> {
25
25
  return (value): value is T[] => Array.isArray(value) && value.every(guard);
26
26
  }
27
27
 
28
+ export function isTupleOf<T extends readonly unknown[]>(
29
+ ...tupleGuards: GuardSchemaOf<T>
30
+ ): Guard<T> {
31
+ if (tupleGuards.some((guard) => typeof guard !== "function")) {
32
+ throw new TypeError(
33
+ `isTupleOf expects guard parameters. Got instead: ${JSON.stringify(
34
+ tupleGuards
35
+ )}`
36
+ );
37
+ }
38
+
39
+ return (value): value is T =>
40
+ Array.isArray(value) &&
41
+ value.length === tupleGuards.length &&
42
+ tupleGuards.every((guard, i) => guard(value[i]));
43
+ }
44
+
28
45
  export function isRecordOf<K extends ObjectKey>(
29
46
  keyGuard: Guard<K>
30
47
  ): Guard<Record<K, unknown>>;
@@ -57,17 +74,22 @@ export function isRecordOf<K extends ObjectKey, V>(
57
74
 
58
75
  export function isObjectOf<O extends object>(
59
76
  schema: GuardSchemaOf<O>
60
- ): O extends unknown[] ? never : Guard<O> {
77
+ ): O extends unknown[] ? never : {} extends O ? never : Guard<O> {
78
+ if (schema == null || typeof schema !== "object") {
79
+ throw new TypeError(
80
+ `isObjectOf expects a guard schema object. Got instead: ${schema}`
81
+ );
82
+ }
83
+
61
84
  const schemaKeys = objectKeys(schema);
62
- const schemaUnknown = schema as unknown;
63
85
  if (
64
- schemaUnknown == null ||
65
- typeof schemaUnknown !== "object" ||
66
- Array.isArray(schemaUnknown) ||
67
- schemaKeys.some((key) => typeof (schemaUnknown as O)[key] !== "function")
86
+ Array.isArray(schema) ||
87
+ schemaKeys.some((key) => typeof schema[key] !== "function")
68
88
  ) {
69
89
  throw new TypeError(
70
- `isObjectOf expects a guard schema. Got instead: ${schemaUnknown}`
90
+ `isObjectOf expects a guard schema object. Got instead ${JSON.stringify(
91
+ schema
92
+ )}`
71
93
  );
72
94
  } else if (schemaKeys.length === 0) {
73
95
  throw new Error("isObjectOf received an empty schema");
@@ -79,5 +101,5 @@ export function isObjectOf<O extends object>(
79
101
  !Array.isArray(value) &&
80
102
  schemaKeys.every(
81
103
  (key) => key in value && schema[key]((value as O)[key])
82
- )) as O extends unknown[] ? never : Guard<O>;
104
+ )) as O extends unknown[] ? never : {} extends O ? never : Guard<O>;
83
105
  }
@@ -1,14 +1,15 @@
1
1
  import {
2
2
  isExact,
3
+ isIntersectionOf,
4
+ isNonNullable,
3
5
  isNot,
4
6
  isNullable,
5
- isNonNullable,
7
+ isNumber,
6
8
  isOneOf,
7
9
  isOptional,
10
+ isString,
8
11
  isUnionOf,
9
- isIntersectionOf,
10
- } from "../src/compound";
11
- import { isNumber, isString } from "../src/primitives";
12
+ } from "../src";
12
13
 
13
14
  describe("isOptional", () => {
14
15
  const guard = isOptional(isString);
@@ -0,0 +1,15 @@
1
+ import { isDiscriminatedObjectOf, isObjectOf, isString } from "../src";
2
+
3
+ describe("isDiscriminatedObjectOf", () => {
4
+ const guard = isDiscriminatedObjectOf("foo", isObjectOf({ bar: isString }));
5
+
6
+ it("succeeds for an object of the value", () => {
7
+ expect(guard({ type: "foo", bar: "baz" })).toBe(true);
8
+ });
9
+
10
+ it("fails for any other value", () => {
11
+ expect(guard({ type: "foo" })).toBe(false);
12
+ expect(guard({ bar: "baz" })).toBe(false);
13
+ expect(guard(1)).toBe(false);
14
+ });
15
+ });
@@ -1,91 +1,91 @@
1
- import {
2
- isBoolean,
3
- isFunction,
4
- isInteger,
5
- isNull,
6
- isNumber,
7
- isString,
8
- isUndefined,
9
- isUnknown,
10
- } from "../src/primitives";
11
-
12
- describe("isUnknown", () => {
13
- it("succeeds for any value", () => {
14
- expect(isUnknown("unknown")).toBe(true);
15
- });
16
- });
17
-
18
- describe("isAnyFunction", () => {
19
- it("succeeds for a function", () => {
20
- expect(isFunction(() => {})).toBe(true);
21
- });
22
-
23
- it("fails for any other value", () => {
24
- expect(isFunction(1)).toBe(false);
25
- });
26
- });
27
-
28
- describe("isNull", () => {
29
- it("succeeds for null", () => {
30
- expect(isNull(null)).toBe(true);
31
- });
32
-
33
- it("fails for any other value", () => {
34
- expect(isNull(undefined)).toBe(false);
35
- });
36
- });
37
-
38
- describe("isUndefined", () => {
39
- it("succeeds for undefined", () => {
40
- expect(isUndefined(undefined)).toBe(true);
41
- });
42
-
43
- it("fails for any other value", () => {
44
- expect(isUndefined(null)).toBe(false);
45
- });
46
- });
47
-
48
- describe("isNumber", () => {
49
- it("succeeds for a number", () => {
50
- expect(isNumber(1.23)).toBe(true);
51
- });
52
-
53
- it("fails for any other type", () => {
54
- expect(isNumber("foo")).toBe(false);
55
- });
56
- });
57
-
58
- describe("isInteger", () => {
59
- it("succeeds for an integer", () => {
60
- expect(isInteger(1)).toBe(true);
61
- });
62
-
63
- it("fails for a non-integer", () => {
64
- expect(isInteger(1.23)).toBe(false);
65
- });
66
-
67
- it("fails for any other type", () => {
68
- expect(isInteger("foo")).toBe(false);
69
- });
70
- });
71
-
72
- describe("isString", () => {
73
- it("succeeds for a string", () => {
74
- expect(isString("Foo bar")).toBe(true);
75
- });
76
-
77
- it("fails for other types", () => {
78
- expect(isString(true)).toBe(false);
79
- });
80
- });
81
-
82
- describe("isBoolean", () => {
83
- it("succeeds for a boolean", () => {
84
- expect(isBoolean(true)).toBe(true);
85
- expect(isBoolean(false)).toBe(true);
86
- });
87
-
88
- it("fails for other types", () => {
89
- expect(isBoolean("foo")).toBe(false);
90
- });
91
- });
1
+ import {
2
+ isBoolean,
3
+ isFunction,
4
+ isInteger,
5
+ isNull,
6
+ isNumber,
7
+ isString,
8
+ isUndefined,
9
+ isUnknown,
10
+ } from "../src";
11
+
12
+ describe("isUnknown", () => {
13
+ it("succeeds for any value", () => {
14
+ expect(isUnknown("unknown")).toBe(true);
15
+ });
16
+ });
17
+
18
+ describe("isAnyFunction", () => {
19
+ it("succeeds for a function", () => {
20
+ expect(isFunction(() => {})).toBe(true);
21
+ });
22
+
23
+ it("fails for any other value", () => {
24
+ expect(isFunction(1)).toBe(false);
25
+ });
26
+ });
27
+
28
+ describe("isNull", () => {
29
+ it("succeeds for null", () => {
30
+ expect(isNull(null)).toBe(true);
31
+ });
32
+
33
+ it("fails for any other value", () => {
34
+ expect(isNull(undefined)).toBe(false);
35
+ });
36
+ });
37
+
38
+ describe("isUndefined", () => {
39
+ it("succeeds for undefined", () => {
40
+ expect(isUndefined(undefined)).toBe(true);
41
+ });
42
+
43
+ it("fails for any other value", () => {
44
+ expect(isUndefined(null)).toBe(false);
45
+ });
46
+ });
47
+
48
+ describe("isNumber", () => {
49
+ it("succeeds for a number", () => {
50
+ expect(isNumber(1.23)).toBe(true);
51
+ });
52
+
53
+ it("fails for any other type", () => {
54
+ expect(isNumber("foo")).toBe(false);
55
+ });
56
+ });
57
+
58
+ describe("isInteger", () => {
59
+ it("succeeds for an integer", () => {
60
+ expect(isInteger(1)).toBe(true);
61
+ });
62
+
63
+ it("fails for a non-integer", () => {
64
+ expect(isInteger(1.23)).toBe(false);
65
+ });
66
+
67
+ it("fails for any other type", () => {
68
+ expect(isInteger("foo")).toBe(false);
69
+ });
70
+ });
71
+
72
+ describe("isString", () => {
73
+ it("succeeds for a string", () => {
74
+ expect(isString("Foo bar")).toBe(true);
75
+ });
76
+
77
+ it("fails for other types", () => {
78
+ expect(isString(true)).toBe(false);
79
+ });
80
+ });
81
+
82
+ describe("isBoolean", () => {
83
+ it("succeeds for a boolean", () => {
84
+ expect(isBoolean(true)).toBe(true);
85
+ expect(isBoolean(false)).toBe(true);
86
+ });
87
+
88
+ it("fails for other types", () => {
89
+ expect(isBoolean("foo")).toBe(false);
90
+ });
91
+ });
@@ -1,110 +1,128 @@
1
- import { isNumber, isString, isSymbol } from "../src/primitives";
2
- import {
3
- isAnyArray,
4
- isAnyRecord,
5
- isArrayOf,
6
- isObjectOf,
7
- isRecordOf,
8
- } from "../src/structures";
9
-
10
- describe("isAnyArray", () => {
11
- it("succeeds for an array", () => {
12
- expect(isAnyArray([])).toBe(true);
13
- expect(isAnyArray(["foo", 1, true, null])).toBe(true);
14
- });
15
-
16
- it("fails for any other value", () => {
17
- expect(isAnyArray({})).toBe(false);
18
- expect(isAnyArray(1)).toBe(false);
19
- });
20
- });
21
-
22
- describe("isAnyRecord", () => {
23
- it("succeeds for a record", () => {
24
- expect(isAnyRecord({})).toBe(true);
25
- expect(isAnyRecord({ foo: "bar", baz: 1 })).toBe(true);
26
- });
27
-
28
- it("fails for any other value", () => {
29
- expect(isAnyRecord([])).toBe(false);
30
- expect(isAnyRecord(1)).toBe(false);
31
- });
32
- });
33
-
34
- describe("isArrayOf", () => {
35
- const guard = isArrayOf(isString);
36
-
37
- it("succeeds for an array of the value", () => {
38
- expect(guard([])).toBe(true);
39
- expect(guard(["foo", "bar", "baz"])).toBe(true);
40
- });
41
-
42
- it("fails for any other value", () => {
43
- expect(guard([1, 2, 3])).toBe(false);
44
- expect(guard(["foo", "bar", null])).toBe(false);
45
- expect(guard(1)).toBe(false);
46
- });
47
- });
48
-
49
- describe("isObjectOf", () => {
50
- const barSymbol = Symbol("bar");
51
- const guard = isObjectOf({
52
- foo: isString,
53
- [barSymbol]: isNumber,
54
- baz: isObjectOf({
55
- qux: isSymbol,
56
- }),
57
- });
58
-
59
- it("succeeds for an object of the value", () => {
60
- expect(
61
- guard({
62
- foo: "hello",
63
- [barSymbol]: 1,
64
- baz: { qux: Symbol("world!") },
65
- quux: "this should not be checked",
66
- })
67
- ).toBe(true);
68
- });
69
-
70
- it("fails for any other value", () => {
71
- expect(
72
- guard({
73
- foo: "hello",
74
- [barSymbol]: "FAIL",
75
- baz: { qux: Symbol("world!") },
76
- })
77
- ).toBe(false);
78
- expect(guard(1)).toBe(false);
79
- });
80
- });
81
-
82
- describe("isRecordOf", () => {
83
- describe("with valueGuard", () => {
84
- const guard = isRecordOf(isString, isNumber);
85
-
86
- it("succeeds for a record of the key/value types", () => {
87
- expect(guard({})).toBe(true);
88
- expect(guard({ foo: 1, bar: 2 })).toBe(true);
89
- });
90
-
91
- it("fails for any other value", () => {
92
- expect(guard({ foo: "bar", baz: 1 })).toBe(false);
93
- expect(guard(1)).toBe(false);
94
- });
95
- });
96
-
97
- describe("without valueGuard", () => {
98
- const guard = isRecordOf(isString);
99
-
100
- it("succeeds for a record with the key type", () => {
101
- expect(guard({})).toBe(true);
102
- expect(guard({ foo: 1, bar: "baz" })).toBe(true);
103
- });
104
-
105
- it("fails for any other value", () => {
106
- expect(guard({ 1: "foo", [Symbol("bar")]: 1 })).toBe(false);
107
- expect(guard(1)).toBe(false);
108
- });
109
- });
110
- });
1
+ import {
2
+ isAnyArray,
3
+ isAnyRecord,
4
+ isArrayOf,
5
+ isBoolean,
6
+ isNumber,
7
+ isObjectOf,
8
+ isRecordOf,
9
+ isString,
10
+ isSymbol,
11
+ isTupleOf,
12
+ } from "../src";
13
+
14
+ describe("isAnyArray", () => {
15
+ it("succeeds for an array", () => {
16
+ expect(isAnyArray([])).toBe(true);
17
+ expect(isAnyArray(["foo", 1, true, null])).toBe(true);
18
+ });
19
+
20
+ it("fails for any other value", () => {
21
+ expect(isAnyArray({})).toBe(false);
22
+ expect(isAnyArray(1)).toBe(false);
23
+ });
24
+ });
25
+
26
+ describe("isAnyRecord", () => {
27
+ it("succeeds for a record", () => {
28
+ expect(isAnyRecord({})).toBe(true);
29
+ expect(isAnyRecord({ foo: "bar", baz: 1 })).toBe(true);
30
+ });
31
+
32
+ it("fails for any other value", () => {
33
+ expect(isAnyRecord([])).toBe(false);
34
+ expect(isAnyRecord(1)).toBe(false);
35
+ });
36
+ });
37
+
38
+ describe("isArrayOf", () => {
39
+ const guard = isArrayOf(isString);
40
+
41
+ it("succeeds for an array of the value", () => {
42
+ expect(guard([])).toBe(true);
43
+ expect(guard(["foo", "bar", "baz"])).toBe(true);
44
+ });
45
+
46
+ it("fails for any other value", () => {
47
+ expect(guard([1, 2, 3])).toBe(false);
48
+ expect(guard(["foo", "bar", null])).toBe(false);
49
+ expect(guard(1)).toBe(false);
50
+ });
51
+ });
52
+
53
+ describe("isTupleOf", () => {
54
+ const guard = isTupleOf(isNumber, isString, isBoolean);
55
+
56
+ it("succeeds for an array of the value", () => {
57
+ expect(guard([1, "foo", true])).toBe(true);
58
+ });
59
+
60
+ it("fails for any other value", () => {
61
+ expect(guard([1, "foo", true, null])).toBe(false);
62
+ expect(guard([1, "foo"])).toBe(false);
63
+ expect(guard(1)).toBe(false);
64
+ });
65
+ });
66
+
67
+ describe("isObjectOf", () => {
68
+ const barSymbol = Symbol("bar");
69
+ const guard = isObjectOf({
70
+ foo: isString,
71
+ [barSymbol]: isNumber,
72
+ baz: isObjectOf({
73
+ qux: isSymbol,
74
+ }),
75
+ });
76
+
77
+ it("succeeds for an object of the value", () => {
78
+ expect(
79
+ guard({
80
+ foo: "hello",
81
+ [barSymbol]: 1,
82
+ baz: { qux: Symbol("world!") },
83
+ quux: "this should not be checked",
84
+ })
85
+ ).toBe(true);
86
+ });
87
+
88
+ it("fails for any other value", () => {
89
+ expect(
90
+ guard({
91
+ foo: "hello",
92
+ [barSymbol]: "FAIL",
93
+ baz: { qux: Symbol("world!") },
94
+ })
95
+ ).toBe(false);
96
+ expect(guard(1)).toBe(false);
97
+ });
98
+ });
99
+
100
+ describe("isRecordOf", () => {
101
+ describe("with valueGuard", () => {
102
+ const guard = isRecordOf(isString, isNumber);
103
+
104
+ it("succeeds for a record of the key/value types", () => {
105
+ expect(guard({})).toBe(true);
106
+ expect(guard({ foo: 1, bar: 2 })).toBe(true);
107
+ });
108
+
109
+ it("fails for any other value", () => {
110
+ expect(guard({ foo: "bar", baz: 1 })).toBe(false);
111
+ expect(guard(1)).toBe(false);
112
+ });
113
+ });
114
+
115
+ describe("without valueGuard", () => {
116
+ const guard = isRecordOf(isString);
117
+
118
+ it("succeeds for a record with the key type", () => {
119
+ expect(guard({})).toBe(true);
120
+ expect(guard({ foo: 1, bar: "baz" })).toBe(true);
121
+ });
122
+
123
+ it("fails for any other value", () => {
124
+ expect(guard({ 1: "foo", [Symbol("bar")]: 1 })).toBe(false);
125
+ expect(guard(1)).toBe(false);
126
+ });
127
+ });
128
+ });