deep-guards 1.1.0 → 1.2.0

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/LICENSE CHANGED
@@ -186,7 +186,7 @@
186
186
  same "printed page" as the copyright notice for easier
187
187
  identification within third-party archives.
188
188
 
189
- Copyright [yyyy] [name of copyright owner]
189
+ Copyright 2024 Niall Coleman-Clarke
190
190
 
191
191
  Licensed under the Apache License, Version 2.0 (the "License");
192
192
  you may not use this file except in compliance with the License.
@@ -12,4 +12,5 @@ type ArrayToIntersection<A extends readonly unknown[]> = A extends [
12
12
  ] ? T & ArrayToIntersection<R> : unknown;
13
13
  export declare function isIntersectionOf<T extends readonly unknown[]>(...guards: GuardSchemaOf<T>): Guard<ArrayToIntersection<T>>;
14
14
  export declare function isExact<const T>(expected: T, deep?: boolean): Guard<T>;
15
+ export declare function isInstance<C extends abstract new (...args: any) => unknown>(cls: C): Guard<InstanceType<C>>;
15
16
  export {};
package/dist/compound.js CHANGED
@@ -61,4 +61,8 @@ export function isExact(expected, deep = true) {
61
61
  !Array.isArray(value) &&
62
62
  objectEntriesChecks(expected, value)));
63
63
  }
64
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
65
+ export function isInstance(cls) {
66
+ return (value) => value instanceof cls;
67
+ }
64
68
  //# sourceMappingURL=compound.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"compound.js","sourceRoot":"src/","sources":["compound.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAK1C,MAAM,UAAU,UAAU,CAAI,KAAe;IAC3C,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE,CAAC;QAChC,MAAM,IAAI,SAAS,CACjB,sDAAsD,KAAK,EAAE,CAC9D,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,KAAK,EAA0B,EAAE,CAAC,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;AAChF,CAAC;AAED,MAAM,UAAU,UAAU,CAAI,KAAe;IAC3C,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE,CAAC;QAChC,MAAM,IAAI,SAAS,CACjB,sDAAsD,KAAK,EAAE,CAC9D,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,KAAc,EAAiC,EAAE,CACvD,KAAK,IAAI,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,KAA2B;IAE3B,OAAO,KAAK,IAAI,IAAI,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,KAAK,CAAU,KAAe;IAC5C,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE,CAAC;QAChC,MAAM,IAAI,SAAS,CACjB,iDAAiD,KAAK,EAAE,CACzD,CAAC;IACJ,CAAC;IAED,OAAO,CAAU,KAAY,EAAc,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,OAAO,CAErB,GAAG,MAAS;IACZ,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;IACjC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAE,QAAQ,CAAC,GAAwB,CAAC,KAAK,CAAC,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,SAAS,CACvB,GAAG,MAAwB;IAE3B,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,UAAU,CAAC,EAAE,CAAC;QACzD,MAAM,IAAI,SAAS,CACjB,sDAAsD,MAAM,EAAE,CAC/D,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,KAAK,EAAc,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;AACrE,CAAC;AASD,MAAM,UAAU,gBAAgB,CAC9B,GAAG,MAAwB;IAE3B,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,UAAU,CAAC,EAAE,CAAC;QACzD,MAAM,IAAI,SAAS,CACjB,6DAA6D,MAAM,EAAE,CACtE,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,KAAK,EAAmC,EAAE,CAChD,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;AAC1C,CAAC;AAED,SAAS,mBAAmB,CAAmB,CAAI,EAAE,CAAS;IAC5D,MAAM,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;IAC5B,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IACvC,OAAO,CACL,KAAK,CAAC,MAAM,KAAK,OAAO,CAAC,IAAI;QAC7B,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAChE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,OAAO,CAAU,QAAW,EAAE,OAAgB,IAAI;IAChE,OAAO,CAAC,KAAK,EAAc,EAAE;IAC3B,iBAAiB;IACjB,QAAQ,KAAK,KAAK;QAClB,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC/C,CAAC,IAAI;YACH,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;gBACtB,CAAC,CAAC,eAAe;oBACf,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;wBACpB,QAAQ,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM;wBAChC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBACtD,CAAC,CAAC,gBAAgB;oBAChB,QAAQ,IAAI,IAAI;wBAChB,KAAK,IAAI,IAAI;wBACb,OAAO,QAAQ,KAAK,QAAQ;wBAC5B,OAAO,KAAK,KAAK,QAAQ;wBACzB,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;wBACrB,mBAAmB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;AACjD,CAAC"}
1
+ {"version":3,"file":"compound.js","sourceRoot":"src/","sources":["compound.ts"],"names":[],"mappings":"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"}
@@ -7,7 +7,5 @@ export const isString = (value) => typeof value === "string";
7
7
  export const isSymbol = (value) => typeof value === "symbol";
8
8
  export const isBoolean = (value) => value === true || value === false;
9
9
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
10
- export const isFunction = (value
11
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
12
- ) => typeof value === "function";
10
+ export const isFunction = (value) => typeof value === "function";
13
11
  //# sourceMappingURL=primitives.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"primitives.js","sourceRoot":"src/","sources":["primitives.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,SAAS,GAAmB,CAAC,MAAM,EAAqB,EAAE,CAAC,IAAI,CAAC;AAE7E,MAAM,CAAC,MAAM,MAAM,GAAgB,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,IAAI,CAAC;AAE7D,MAAM,CAAC,MAAM,WAAW,GAAqB,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC;AAE5E,MAAM,CAAC,MAAM,QAAQ,GAAkB,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC;AAE5E,MAAM,CAAC,MAAM,SAAS,GAAkB,CAAC,KAAK,EAAmB,EAAE,CACjE,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;AAE1B,MAAM,CAAC,MAAM,QAAQ,GAAkB,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC;AAE5E,MAAM,CAAC,MAAM,QAAQ,GAAkB,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC;AAE5E,MAAM,CAAC,MAAM,SAAS,GAAmB,CAAC,KAAK,EAAE,EAAE,CACjD,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,KAAK,CAAC;AAEpC,8DAA8D;AAC9D,MAAM,CAAC,MAAM,UAAU,GAAuC,CAC5D,KAAK;AACL,8DAA8D;EACxB,EAAE,CAAC,OAAO,KAAK,KAAK,UAAU,CAAC"}
1
+ {"version":3,"file":"primitives.js","sourceRoot":"src/","sources":["primitives.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,SAAS,GAAmB,CAAC,MAAM,EAAqB,EAAE,CAAC,IAAI,CAAC;AAE7E,MAAM,CAAC,MAAM,MAAM,GAAgB,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,IAAI,CAAC;AAE7D,MAAM,CAAC,MAAM,WAAW,GAAqB,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC;AAE5E,MAAM,CAAC,MAAM,QAAQ,GAAkB,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC;AAE5E,MAAM,CAAC,MAAM,SAAS,GAAkB,CAAC,KAAK,EAAmB,EAAE,CACjE,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;AAE1B,MAAM,CAAC,MAAM,QAAQ,GAAkB,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC;AAE5E,MAAM,CAAC,MAAM,QAAQ,GAAkB,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC;AAE5E,MAAM,CAAC,MAAM,SAAS,GAAmB,CAAC,KAAK,EAAE,EAAE,CACjD,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,KAAK,CAAC;AAEpC,8DAA8D;AAC9D,MAAM,CAAC,MAAM,UAAU,GAAuC,CAC5D,KAAK,EAEiC,EAAE,CAAC,OAAO,KAAK,KAAK,UAAU,CAAC"}
package/package.json CHANGED
@@ -1,18 +1,21 @@
1
1
  {
2
2
  "author": "eniallator",
3
3
  "description": "Deep guarding package",
4
+ "engines": {
5
+ "node": ">=25.4.0"
6
+ },
4
7
  "license": "Apache-2.0",
5
8
  "main": "dist/index.js",
6
9
  "name": "deep-guards",
7
- "packageManager": "yarn@4.9.2",
10
+ "packageManager": "yarn@4.12.0",
8
11
  "type": "module",
9
12
  "types": "dist/index.d.ts",
10
13
  "homepage": "https://github.com/eniallator/Deep-Guards",
11
- "version": "1.1.0",
14
+ "version": "1.2.0",
12
15
  "scripts": {
13
- "test": "jest",
16
+ "test": "vitest run --passWithNoTests",
14
17
  "build": "tsc",
15
- "lint": "eslint ./src ./tests",
18
+ "lint": "eslint ./src",
16
19
  "typecheck": "tsc --noEmit",
17
20
  "findissues": "yarn typecheck && yarn lint",
18
21
  "publish": "npm publish --tolerate-republish",
@@ -21,34 +24,18 @@
21
24
  "release": "powershell -ExecutionPolicy Bypass -File ./scripts/release.ps1"
22
25
  },
23
26
  "devDependencies": {
24
- "@babel/core": "^7.28.3",
25
- "@babel/preset-env": "^7.28.3",
26
- "@babel/preset-typescript": "^7.27.1",
27
- "@eslint/compat": "^1.3.2",
28
- "@eslint/js": "^9.33.0",
29
- "@jest/globals": "^30.0.5",
30
- "@stylistic/eslint-plugin": "^5.2.3",
31
- "@types/babel__core": "^7.20.5",
32
- "@types/babel__preset-env": "^7.10.0",
27
+ "@eslint/compat": "^2.0.2",
28
+ "@eslint/js": "^9.39.2",
29
+ "@stylistic/eslint-plugin": "^5.8.0",
33
30
  "@types/eslint__js": "^9.14.0",
34
- "@types/jest": "^30.0.0",
35
- "@typescript-eslint/eslint-plugin": "^8.39.1",
36
- "@typescript-eslint/parser": "^8.39.1",
37
- "babel-jest": "^30.0.5",
38
- "eslint": "^9.33.0",
31
+ "@types/node": "^25.2.3",
32
+ "@typescript-eslint/eslint-plugin": "^8.55.0",
33
+ "@typescript-eslint/parser": "^8.55.0",
34
+ "eslint": "^9.39.2",
39
35
  "eslint-plugin-eslint-comments": "^3.2.0",
40
36
  "eslint-plugin-import": "^2.32.0",
41
- "eslint-plugin-jest": "^29.0.1",
42
- "jest": "^30.0.5",
43
- "ts-jest": "^29.4.1",
44
- "typescript": "^5.9.2",
45
- "typescript-eslint": "^8.39.1"
46
- },
47
- "jest": {
48
- "globals": {
49
- "ts-jest": {
50
- "tsConfig": "tsconfig.test.json"
51
- }
52
- }
37
+ "typescript": "^5.9.3",
38
+ "typescript-eslint": "^8.55.0",
39
+ "vitest": "^4.0.18"
53
40
  }
54
41
  }
@@ -1,17 +1,17 @@
1
- import { describe, expect, it } from "@jest/globals";
1
+ import { describe, expect, it } from "vitest";
2
2
 
3
3
  import {
4
4
  isExact,
5
+ isInstance,
5
6
  isIntersectionOf,
6
7
  isNonNullable,
7
8
  isNot,
8
9
  isNullable,
9
- isNumber,
10
10
  isOneOf,
11
11
  isOptional,
12
- isString,
13
12
  isUnionOf,
14
- } from "../dist";
13
+ } from "./compound.ts";
14
+ import { isNumber, isString } from "./primitives.ts";
15
15
 
16
16
  describe("isOptional", () => {
17
17
  const guard = isOptional(isString);
@@ -97,7 +97,7 @@ describe("isUnionOf", () => {
97
97
  describe("isIntersectionOf", () => {
98
98
  const guard = isIntersectionOf(
99
99
  isOneOf("foo", "bar", "baz"),
100
- isExact("foo", false)
100
+ isExact("foo", false),
101
101
  );
102
102
 
103
103
  it("succeeds for the intersection", () => {
@@ -114,21 +114,21 @@ describe("isExact", () => {
114
114
  describe("deep", () => {
115
115
  const guard = isExact(
116
116
  { foo: "bar", hello: ["world", { key: "test" }] },
117
- true
117
+ true,
118
118
  );
119
119
 
120
120
  it("succeeds for the exact value", () => {
121
121
  expect(guard({ foo: "bar", hello: ["world", { key: "test" }] })).toBe(
122
- true
122
+ true,
123
123
  );
124
124
  });
125
125
 
126
126
  it("fails for any other value", () => {
127
127
  expect(guard({ foo: "baz", hello: ["world", { key: "test" }] })).toBe(
128
- false
128
+ false,
129
129
  );
130
130
  expect(guard({ foo: "bar", hello: ["world", { key: "tester" }] })).toBe(
131
- false
131
+ false,
132
132
  );
133
133
  expect(guard(1)).toBe(false);
134
134
  });
@@ -152,3 +152,23 @@ describe("isExact", () => {
152
152
  });
153
153
  });
154
154
  });
155
+
156
+ describe("isInstance", () => {
157
+ class Test {
158
+ foo: string = "bar";
159
+
160
+ constructor(foo: string) {
161
+ this.foo = foo;
162
+ }
163
+ }
164
+ const guard = isInstance(Test);
165
+
166
+ it("succeeds for an instance", () => {
167
+ expect(guard(new Test("baz"))).toBe(true);
168
+ });
169
+
170
+ it("fails for any other type", () => {
171
+ expect(guard({})).toBe(false);
172
+ expect(guard(null)).toBe(false);
173
+ });
174
+ });
package/src/compound.ts CHANGED
@@ -6,7 +6,7 @@ import type { Guard } from "./types.js";
6
6
  export function isOptional<T>(guard: Guard<T>): Guard<T | undefined> {
7
7
  if (typeof guard !== "function") {
8
8
  throw new TypeError(
9
- `isOptional expects a guard parameter. Got instead: ${guard}`
9
+ `isOptional expects a guard parameter. Got instead: ${guard}`,
10
10
  );
11
11
  }
12
12
 
@@ -16,7 +16,7 @@ export function isOptional<T>(guard: Guard<T>): Guard<T | undefined> {
16
16
  export function isNullable<T>(guard: Guard<T>): Guard<T | null | undefined> {
17
17
  if (typeof guard !== "function") {
18
18
  throw new TypeError(
19
- `isNullable expects a guard parameter. Got instead: ${guard}`
19
+ `isNullable expects a guard parameter. Got instead: ${guard}`,
20
20
  );
21
21
  }
22
22
 
@@ -25,7 +25,7 @@ export function isNullable<T>(guard: Guard<T>): Guard<T | null | undefined> {
25
25
  }
26
26
 
27
27
  export function isNonNullable<T extends NonNullable<unknown>>(
28
- value: T | null | undefined
28
+ value: T | null | undefined,
29
29
  ): value is T {
30
30
  return value != null;
31
31
  }
@@ -33,7 +33,7 @@ export function isNonNullable<T extends NonNullable<unknown>>(
33
33
  export function isNot<const N>(guard: Guard<N>) {
34
34
  if (typeof guard !== "function") {
35
35
  throw new TypeError(
36
- `isNot expects a guard parameter. Got instead: ${guard}`
36
+ `isNot expects a guard parameter. Got instead: ${guard}`,
37
37
  );
38
38
  }
39
39
 
@@ -41,7 +41,7 @@ export function isNot<const N>(guard: Guard<N>) {
41
41
  }
42
42
 
43
43
  export function isOneOf<
44
- const T extends (string | number | boolean | symbol | null | undefined)[]
44
+ const T extends (string | number | boolean | symbol | null | undefined)[],
45
45
  >(...values: T): Guard<T[number]> {
46
46
  const valueSet = new Set(values);
47
47
  return (value) => (valueSet.has as Guard<T[number]>)(value);
@@ -52,7 +52,7 @@ export function isUnionOf<T extends readonly unknown[]>(
52
52
  ): Guard<T[number]> {
53
53
  if (guards.every((guard) => typeof guard !== "function")) {
54
54
  throw new TypeError(
55
- `isUnionOf expects N guard parameters. Got instead: ${guards}`
55
+ `isUnionOf expects N guard parameters. Got instead: ${guards}`,
56
56
  );
57
57
  }
58
58
 
@@ -61,7 +61,7 @@ export function isUnionOf<T extends readonly unknown[]>(
61
61
 
62
62
  type ArrayToIntersection<A extends readonly unknown[]> = A extends [
63
63
  infer T,
64
- ...infer R
64
+ ...infer R,
65
65
  ]
66
66
  ? T & ArrayToIntersection<R>
67
67
  : unknown;
@@ -71,7 +71,7 @@ export function isIntersectionOf<T extends readonly unknown[]>(
71
71
  ): Guard<ArrayToIntersection<T>> {
72
72
  if (guards.every((guard) => typeof guard !== "function")) {
73
73
  throw new TypeError(
74
- `isIntersectionOf expects N guard parameters. Got instead: ${guards}`
74
+ `isIntersectionOf expects N guard parameters. Got instead: ${guards}`,
75
75
  );
76
76
  }
77
77
 
@@ -107,3 +107,10 @@ export function isExact<const T>(expected: T, deep: boolean = true): Guard<T> {
107
107
  !Array.isArray(value) &&
108
108
  objectEntriesChecks(expected, value)));
109
109
  }
110
+
111
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
112
+ export function isInstance<C extends abstract new (...args: any) => unknown>(
113
+ cls: C,
114
+ ): Guard<InstanceType<C>> {
115
+ return (value): value is InstanceType<C> => value instanceof cls;
116
+ }
package/src/errors.ts CHANGED
@@ -7,7 +7,7 @@ export class GuardError extends Error {
7
7
  export function guardOrThrow<T>(
8
8
  value: unknown,
9
9
  guard: Guard<T>,
10
- hint?: string
10
+ hint?: string,
11
11
  ): T {
12
12
  if (guard(value)) {
13
13
  return value;
package/src/helpers.ts CHANGED
@@ -8,12 +8,12 @@ export type ObjectKey = string | number | symbol;
8
8
 
9
9
  export const objectKeys = <K extends ObjectKey>(obj: Record<K, unknown>): K[] =>
10
10
  (Object.getOwnPropertyNames(obj) as K[]).concat(
11
- Object.getOwnPropertySymbols(obj) as K[]
11
+ Object.getOwnPropertySymbols(obj) as K[],
12
12
  );
13
13
 
14
14
  export function omit<O extends NonNullable<unknown>>(
15
15
  obj: O,
16
- key: keyof O
16
+ key: keyof O,
17
17
  ): { [K in keyof O as K extends typeof key ? never : K]: O[K] } {
18
18
  const omitted = { ...obj };
19
19
  // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
@@ -1,12 +1,14 @@
1
- import { describe, expect, it } from "@jest/globals";
1
+ import { describe, expect, it } from "vitest";
2
2
 
3
- import { isDiscriminatedObjectOf, isObjectOf, isString } from "../dist";
3
+ import { isDiscriminatedObjectOf } from "./macros.ts";
4
+ import { isString } from "./primitives.ts";
5
+ import { isObjectOf } from "./structures.ts";
4
6
 
5
7
  describe("isDiscriminatedObjectOf", () => {
6
8
  describe("no key override", () => {
7
9
  const guard = isDiscriminatedObjectOf(
8
10
  "foo",
9
- isObjectOf({ bar: isString }, true)
11
+ isObjectOf({ bar: isString }, true),
10
12
  );
11
13
 
12
14
  it("succeeds for an object of the value", () => {
@@ -24,7 +26,7 @@ describe("isDiscriminatedObjectOf", () => {
24
26
  const guard = isDiscriminatedObjectOf(
25
27
  "foo",
26
28
  isObjectOf({ bar: isString }, true),
27
- "test"
29
+ "test",
28
30
  );
29
31
 
30
32
  it("succeeds for an object of the value", () => {
package/src/macros.ts CHANGED
@@ -7,20 +7,20 @@ import type { Guard } from "./types.js";
7
7
 
8
8
  export function isDiscriminatedObjectOf<
9
9
  const T extends string,
10
- O extends object
10
+ O extends object,
11
11
  >(value: T, guard: Guard<O>): Guard<{ type: T } & O>;
12
12
  export function isDiscriminatedObjectOf<
13
13
  const T extends string,
14
14
  O extends object,
15
- const K extends ObjectKey
15
+ const K extends ObjectKey,
16
16
  >(value: T, guard: Guard<O>, key: K): Guard<{ [S in K]: T } & O>;
17
17
  export function isDiscriminatedObjectOf<
18
18
  const T extends string,
19
- O extends object
19
+ O extends object,
20
20
  >(
21
21
  value: T,
22
22
  guard: Guard<O>,
23
- key: ObjectKey = "type"
23
+ key: ObjectKey = "type",
24
24
  ): Guard<Record<ObjectKey, T> & O> {
25
25
  const discriminatorGuard = isObjectOf({ [key]: isExact(value) }) as Guard<
26
26
  Record<ObjectKey, T>
@@ -1,4 +1,4 @@
1
- import { describe, expect, it } from "@jest/globals";
1
+ import { describe, expect, it } from "vitest";
2
2
 
3
3
  import {
4
4
  isBoolean,
@@ -9,7 +9,7 @@ import {
9
9
  isString,
10
10
  isUndefined,
11
11
  isUnknown,
12
- } from "../dist";
12
+ } from "./primitives.ts";
13
13
 
14
14
  describe("isUnknown", () => {
15
15
  it("succeeds for any value", () => {
package/src/primitives.ts CHANGED
@@ -20,6 +20,6 @@ export const isBoolean: Guard<boolean> = (value) =>
20
20
 
21
21
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
22
22
  export const isFunction: Guard<(...args: any[]) => unknown> = (
23
- value
23
+ value,
24
24
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
25
25
  ): value is (...args: any[]) => unknown => typeof value === "function";
@@ -1,17 +1,14 @@
1
- import { describe, expect, it } from "@jest/globals";
1
+ import { describe, expect, it } from "vitest";
2
2
 
3
+ import { isBoolean, isNumber, isString, isSymbol } from "./primitives.ts";
3
4
  import {
4
5
  isAnyArray,
5
6
  isAnyRecord,
6
7
  isArrayOf,
7
- isBoolean,
8
- isNumber,
9
8
  isObjectOf,
10
9
  isRecordOf,
11
- isString,
12
- isSymbol,
13
10
  isTupleOf,
14
- } from "../dist";
11
+ } from "./structures.ts";
15
12
 
16
13
  describe("isAnyArray", () => {
17
14
  it("succeeds for an array", () => {
@@ -84,7 +81,7 @@ describe("isObjectOf", () => {
84
81
  [barSymbol]: 1,
85
82
  baz: { qux: Symbol("world!") },
86
83
  quux: "this should not be checked",
87
- })
84
+ }),
88
85
  ).toBe(true);
89
86
  });
90
87
 
@@ -94,7 +91,7 @@ describe("isObjectOf", () => {
94
91
  foo: "hello",
95
92
  [barSymbol]: "FAIL",
96
93
  baz: { qux: Symbol("world!") },
97
- })
94
+ }),
98
95
  ).toBe(false);
99
96
  expect(guard(1)).toBe(false);
100
97
  });
@@ -110,7 +107,7 @@ describe("isObjectOf", () => {
110
107
  qux: isSymbol,
111
108
  }),
112
109
  },
113
- true
110
+ true,
114
111
  );
115
112
 
116
113
  it("succeeds for an object of the value", () => {
@@ -119,7 +116,7 @@ describe("isObjectOf", () => {
119
116
  foo: "hello",
120
117
  [barSymbol]: 1,
121
118
  baz: { qux: Symbol("world!") },
122
- })
119
+ }),
123
120
  ).toBe(true);
124
121
  });
125
122
 
@@ -130,14 +127,14 @@ describe("isObjectOf", () => {
130
127
  [barSymbol]: 1,
131
128
  baz: { qux: Symbol("world!") },
132
129
  quux: "this should be checked",
133
- })
130
+ }),
134
131
  ).toBe(false);
135
132
  expect(
136
133
  guard({
137
134
  foo: "hello",
138
135
  [barSymbol]: "FAIL",
139
136
  baz: { qux: Symbol("world!") },
140
- })
137
+ }),
141
138
  ).toBe(false);
142
139
  expect(guard(1)).toBe(false);
143
140
  });
package/src/structures.ts CHANGED
@@ -6,14 +6,14 @@ import type { Guard } from "./types.js";
6
6
  export const isAnyArray: Guard<unknown[]> = (value) => Array.isArray(value);
7
7
 
8
8
  export const isAnyRecord: Guard<Record<ObjectKey, unknown>> = (
9
- value
9
+ value,
10
10
  ): value is Record<ObjectKey, unknown> =>
11
11
  value != null && typeof value === "object" && !Array.isArray(value);
12
12
 
13
13
  export function isArrayOf<T>(guard: Guard<T>): Guard<T[]> {
14
14
  if (typeof guard !== "function") {
15
15
  throw new TypeError(
16
- `isArrayOf expects a guard parameter. Got instead: ${guard}`
16
+ `isArrayOf expects a guard parameter. Got instead: ${guard}`,
17
17
  );
18
18
  }
19
19
 
@@ -26,8 +26,8 @@ export function isTupleOf<T extends readonly unknown[]>(
26
26
  if (tupleGuards.some((guard) => typeof guard !== "function")) {
27
27
  throw new TypeError(
28
28
  `isTupleOf expects guard parameters. Got instead: ${JSON.stringify(
29
- tupleGuards
30
- )}`
29
+ tupleGuards,
30
+ )}`,
31
31
  );
32
32
  }
33
33
 
@@ -38,23 +38,23 @@ export function isTupleOf<T extends readonly unknown[]>(
38
38
  }
39
39
 
40
40
  export function isRecordOf<K extends ObjectKey>(
41
- keyGuard: Guard<K>
41
+ keyGuard: Guard<K>,
42
42
  ): Guard<Record<K, unknown>>;
43
43
  export function isRecordOf<K extends ObjectKey, V>(
44
44
  keyGuard: Guard<K>,
45
- valueGuard: Guard<V>
45
+ valueGuard: Guard<V>,
46
46
  ): Guard<Record<K, V>>;
47
47
  export function isRecordOf<K extends ObjectKey, V>(
48
48
  keyGuard: Guard<K>,
49
- valueGuard?: Guard<V>
49
+ valueGuard?: Guard<V>,
50
50
  ): Guard<Record<K, V>> {
51
51
  if (typeof keyGuard !== "function") {
52
52
  throw new TypeError(
53
- `isRecordOf keyGuard expects a guard parameter. Got instead: ${keyGuard}`
53
+ `isRecordOf keyGuard expects a guard parameter. Got instead: ${keyGuard}`,
54
54
  );
55
55
  } else if (valueGuard != null && typeof valueGuard !== "function") {
56
56
  throw new TypeError(
57
- `isRecordOf valueGuard expects an optional guard parameter. Got instead: ${valueGuard}`
57
+ `isRecordOf valueGuard expects an optional guard parameter. Got instead: ${valueGuard}`,
58
58
  );
59
59
  }
60
60
 
@@ -63,25 +63,25 @@ export function isRecordOf<K extends ObjectKey, V>(
63
63
  typeof value === "object" &&
64
64
  !Array.isArray(value) &&
65
65
  objectKeys(value).every(
66
- (key) => keyGuard(key) && (valueGuard?.(value[key]) ?? true)
66
+ (key) => keyGuard(key) && (valueGuard?.(value[key]) ?? true),
67
67
  );
68
68
  }
69
69
 
70
70
  type IsObjectOfGuard<O extends object> = O extends unknown[]
71
71
  ? never
72
72
  : // eslint-disable-next-line @typescript-eslint/no-empty-object-type
73
- {} extends O
74
- ? never
75
- : Guard<O>;
73
+ {} extends O
74
+ ? never
75
+ : Guard<O>;
76
76
 
77
77
  export function isObjectOf<O extends object>(
78
78
  schema: GuardSchemaOf<O>,
79
- exactKeys: boolean = false
79
+ exactKeys: boolean = false,
80
80
  ): IsObjectOfGuard<O> {
81
81
  const schemaUnknown: unknown = schema;
82
82
  if (schemaUnknown == null || typeof schemaUnknown !== "object") {
83
83
  throw new TypeError(
84
- `isObjectOf expects a guard schema object. Got instead: ${schemaUnknown}`
84
+ `isObjectOf expects a guard schema object. Got instead: ${schemaUnknown}`,
85
85
  );
86
86
  }
87
87
 
@@ -92,8 +92,8 @@ export function isObjectOf<O extends object>(
92
92
  ) {
93
93
  throw new TypeError(
94
94
  `isObjectOf expects a guard schema object. Got instead ${JSON.stringify(
95
- schema
96
- )}`
95
+ schema,
96
+ )}`,
97
97
  );
98
98
  } else if (schemaKeys.length === 0) {
99
99
  throw new Error("isObjectOf received an empty schema");
@@ -105,6 +105,6 @@ export function isObjectOf<O extends object>(
105
105
  !Array.isArray(value) &&
106
106
  (!exactKeys || schemaKeys.length === objectKeys(value).length) &&
107
107
  schemaKeys.every(
108
- (key) => key in value && schema[key]((value as O)[key])
108
+ (key) => key in value && schema[key]((value as O)[key]),
109
109
  )) as IsObjectOfGuard<O>;
110
110
  }
package/src/types.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  export type Guard<T> = (value: unknown) => value is T;
2
2
 
3
- export type TypeFromGuard<G extends Guard<unknown>> = G extends Guard<infer T>
4
- ? T
5
- : never;
3
+ export type TypeFromGuard<G extends Guard<unknown>> =
4
+ G extends Guard<infer T> ? T : never;
package/tsconfig.json CHANGED
@@ -1,4 +1,5 @@
1
1
  {
2
+ "exclude": ["**/*.test.ts"],
2
3
  "extends": "./tsconfig.common.json",
3
4
  "include": ["src"],
4
5
  "compilerOptions": {
@@ -1,7 +1,4 @@
1
1
  {
2
2
  "extends": "./tsconfig.common.json",
3
- "include": ["tests"],
4
- "compilerOptions": {
5
- "sourceRoot": "test"
6
- }
3
+ "include": ["**/*.test.ts"]
7
4
  }