@rhombus-toolkit/type-guards 2.0.1 → 3.0.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.
@@ -5,25 +5,54 @@ type Func<in Args extends readonly any[] = any[], out Return = any, in This = un
5
5
  /** The `GeneratorFunction` constructor. Named `…Ctor` so it does not shadow the lib interface of the same name. */
6
6
  declare const GeneratorFunctionCtor: GeneratorFunctionConstructor;
7
7
  declare const AsyncGeneratorFunctionCtor: AsyncGeneratorFunctionConstructor;
8
- declare function isArray(value: any): value is any[];
8
+ /**
9
+ * Whether `value` carries `key` at all, whatever it holds.
10
+ *
11
+ * @remarks
12
+ * `K` is a type parameter rather than a plain `PropertyKey` so the narrowing names the key that was
13
+ * actually checked: a literal argument makes the result `Record<'foo', unknown>`, where a widened
14
+ * `PropertyKey` would collapse to an index signature that admits every other key too.
15
+ *
16
+ * `Object(value)` boxes primitives, since `in` demands an object where a property read would have
17
+ * boxed on its own. Testing the member's *value* instead would conflate absence with a falsy
18
+ * member — `''` carries `length`.
19
+ */
20
+ declare function hasMember<K extends PropertyKey>(value: unknown, key: K): value is Record<K, unknown>;
21
+ declare function isObject(value: any): value is object;
22
+ declare function isReadonlyArray(value: any): value is readonly unknown[];
23
+ declare function isArray(value: any): value is unknown[];
24
+ declare function isUndefined(value: any): value is undefined;
9
25
  /** Whether `value` is anything other than `undefined` — `null` is a defined value, so it passes. Use {@link hasValue} to exclude both. */
10
- declare function isDefined<T>(p: T | undefined | null): p is T | null;
26
+ declare function isDefined<T>(p: T | undefined): p is T;
11
27
  declare function hasValue<T>(p: T | null | undefined): p is T;
12
- declare function isFunction(value: any): value is Func;
28
+ /**
29
+ * Whether `value` is callable.
30
+ *
31
+ * @remarks
32
+ * Takes no type arguments: `typeof` witnesses that something is callable and nothing about what it
33
+ * accepts or returns, so letting a caller name those would dress an unchecked assertion up as a
34
+ * guard — a caller who needs a signature should spell the cast out.
35
+ *
36
+ * `Func`'s permissive default is what the narrowing needs, rather than a stricter
37
+ * `Func<unknown[], unknown>`. Parameters are contravariant, so a concrete `Func<[T], U>` is not
38
+ * assignable to the stricter form; narrowing a `U | Func<[T], U>` by it cannot pick the function
39
+ * member and yields a call signature returning `unknown`, losing `U`.
40
+ */
41
+ declare function isFunction(value: unknown): value is Func;
13
42
  /** CONTRACT. Whether `value` is thenable, whatever produced it. */
14
- declare function isPromiseLike(value: any): value is PromiseLike<any>;
43
+ declare function isPromiseLike(value: any): value is PromiseLike<unknown>;
15
44
  /** PROTOTYPE. Whether `value` is a real `Promise`, so `catch`/`finally` are present. A thenable from another realm reads as {@link isPromiseLike} only. */
16
- declare function isPromise(value: any): value is Promise<any>;
45
+ declare function isPromise(value: any): value is Promise<unknown>;
17
46
  /** CONTRACT. Whether `value` has a `next`. Sync and async iterators are indistinguishable by shape — use {@link isAsyncIteratorObject} or {@link isAsyncIterable} to tell them apart. */
18
- declare function isIterator(value: any): value is Iterator<any>;
47
+ declare function isIterator(value: any): value is Iterator<unknown>;
19
48
  /** CONTRACT. Whether `value` yields an iterator when asked. Strings, arrays, `Map` and `Set` all pass. */
20
- declare function isIterable(value: any): value is Iterable<any>;
49
+ declare function isIterable(value: any): value is Iterable<unknown>;
21
50
  /** CONTRACT. Whether `value` is an iterator that is also iterable, the shape a `for…of` accepts directly. */
22
- declare function isIterableIterator(value: any): value is IterableIterator<any>;
51
+ declare function isIterableIterator(value: any): value is IterableIterator<unknown>;
23
52
  /** CONTRACT. Whether `value` yields an async iterator when asked. */
24
- declare function isAsyncIterable(value: any): value is AsyncIterable<any>;
53
+ declare function isAsyncIterable(value: any): value is AsyncIterable<unknown>;
25
54
  /** CONTRACT. Whether `value` is an async iterator that is also async-iterable. */
26
- declare function isAsyncIterableIterator(value: any): value is AsyncIterableIterator<any>;
55
+ declare function isAsyncIterableIterator(value: any): value is AsyncIterableIterator<unknown>;
27
56
  /**
28
57
  * PROTOTYPE. Whether `value` inherits `%IteratorPrototype%`, so the ES2025
29
58
  * iterator helpers (`map`, `filter`, `take`, `drop`, `toArray`, …) are present.
@@ -31,16 +60,16 @@ declare function isAsyncIterableIterator(value: any): value is AsyncIterableIter
31
60
  * @remarks
32
61
  * A hand-rolled `{ next() { … } }` is an {@link isIterator} but not this.
33
62
  */
34
- declare function isIteratorObject(value: any): value is IteratorObject<any, any, any>;
63
+ declare function isIteratorObject(value: any): value is IteratorObject<unknown>;
35
64
  /** PROTOTYPE. The async counterpart of {@link isIteratorObject}. */
36
- declare function isAsyncIteratorObject(value: any): value is AsyncIteratorObject<any, any, any>;
65
+ declare function isAsyncIteratorObject(value: any): value is AsyncIteratorObject<unknown>;
37
66
  /** PROTOTYPE. Whether `value` is a generator *object* — what calling a generator function returns, not the function itself. */
38
- declare function isGenerator(value: any): value is Generator<any, any, any>;
67
+ declare function isGenerator(value: any): value is Generator<unknown>;
39
68
  /** PROTOTYPE. Whether `value` is an async generator object. Never true for a sync generator — the two have distinct intrinsics. */
40
- declare function isAsyncGenerator(value: any): value is AsyncGenerator<any, any, any>;
69
+ declare function isAsyncGenerator(value: any): value is AsyncGenerator<unknown>;
41
70
  /** PROTOTYPE. Whether `value` is a generator *function* — the thing you call to get a generator. */
42
71
  declare function isGeneratorFunction(value: any): value is GeneratorFunction;
43
72
  /** PROTOTYPE. Whether `value` is an async generator function. */
44
73
  declare function isAsyncGeneratorFunction(value: any): value is AsyncGeneratorFunction;
45
74
 
46
- export { AsyncGeneratorFunctionCtor, GeneratorFunctionCtor, assertNever, hasValue, isArray, isAsyncGenerator, isAsyncGeneratorFunction, isAsyncIterable, isAsyncIterableIterator, isAsyncIteratorObject, isDefined, isFunction, isGenerator, isGeneratorFunction, isIterable, isIterableIterator, isIterator, isIteratorObject, isPromise, isPromiseLike };
75
+ export { AsyncGeneratorFunctionCtor, GeneratorFunctionCtor, assertNever, hasMember, hasValue, isArray, isAsyncGenerator, isAsyncGeneratorFunction, isAsyncIterable, isAsyncIterableIterator, isAsyncIteratorObject, isDefined, isFunction, isGenerator, isGeneratorFunction, isIterable, isIterableIterator, isIterator, isIteratorObject, isObject, isPromise, isPromiseLike, isReadonlyArray, isUndefined };
@@ -25,17 +25,26 @@ function inheritsFrom(value, prototype) {
25
25
  return false;
26
26
  }
27
27
  function hasMethod(value, key) {
28
- if (value === null || value === undefined) {
29
- return false;
30
- }
31
- return typeof value[key] === "function";
28
+ return hasMember(value, key) && isFunction(value[key]);
29
+ }
30
+ function hasMember(value, key) {
31
+ return hasValue(value) && key in Object(value);
32
32
  }
33
33
  function typeTag(value) {
34
34
  return Object.prototype.toString.call(value).slice(8, -1);
35
35
  }
36
+ function isObject(value) {
37
+ return hasValue(value) && typeof value === "object";
38
+ }
39
+ function isReadonlyArray(value) {
40
+ return isArray(value);
41
+ }
36
42
  function isArray(value) {
37
43
  return Array.isArray(value);
38
44
  }
45
+ function isUndefined(value) {
46
+ return value === undefined;
47
+ }
39
48
  function isDefined(p) {
40
49
  return p !== undefined;
41
50
  }
@@ -46,22 +55,22 @@ function isFunction(value) {
46
55
  return typeof value === "function";
47
56
  }
48
57
  function isPromiseLike(value) {
49
- return isPromise(value) || typeTag(value) === "Promise" || hasMethod(value, "then");
58
+ return isPromise(value) || hasMethod(value, "then");
50
59
  }
51
60
  function isPromise(value) {
52
- return value instanceof Promise;
61
+ return isObject(value) && value instanceof Promise;
53
62
  }
54
63
  function isIterator(value) {
55
64
  return hasMethod(value, "next");
56
65
  }
57
66
  function isIterable(value) {
58
- return hasMethod(value, Symbol.iterator);
67
+ return isFunction(value?.[Symbol.iterator]);
59
68
  }
60
69
  function isIterableIterator(value) {
61
- return isIterator(value) && isIterable(value);
70
+ return isDefined(value) && isIterator(value) && isIterable(value);
62
71
  }
63
72
  function isAsyncIterable(value) {
64
- return hasMethod(value, Symbol.asyncIterator);
73
+ return isFunction(value?.[Symbol.asyncIterator]);
65
74
  }
66
75
  function isAsyncIterableIterator(value) {
67
76
  return isIterator(value) && isAsyncIterable(value);
@@ -91,24 +100,28 @@ function isAsyncGeneratorFunction(value) {
91
100
  return Object.getPrototypeOf(value) === AsyncGeneratorFunctionPrototype || typeTag(value) === "AsyncGeneratorFunction";
92
101
  }
93
102
  export {
94
- isPromiseLike,
95
- isPromise,
96
- isIteratorObject,
97
- isIterator,
98
- isIterableIterator,
99
- isIterable,
100
- isGeneratorFunction,
101
- isGenerator,
102
- isFunction,
103
- isDefined,
104
- isAsyncIteratorObject,
105
- isAsyncIterableIterator,
106
- isAsyncIterable,
107
- isAsyncGeneratorFunction,
108
- isAsyncGenerator,
109
- isArray,
110
- hasValue,
111
- assertNever,
103
+ AsyncGeneratorFunctionCtor,
112
104
  GeneratorFunctionCtor,
113
- AsyncGeneratorFunctionCtor
105
+ assertNever,
106
+ hasMember,
107
+ hasValue,
108
+ isArray,
109
+ isAsyncGenerator,
110
+ isAsyncGeneratorFunction,
111
+ isAsyncIterable,
112
+ isAsyncIterableIterator,
113
+ isAsyncIteratorObject,
114
+ isDefined,
115
+ isFunction,
116
+ isGenerator,
117
+ isGeneratorFunction,
118
+ isIterable,
119
+ isIterableIterator,
120
+ isIterator,
121
+ isIteratorObject,
122
+ isObject,
123
+ isPromise,
124
+ isPromiseLike,
125
+ isReadonlyArray,
126
+ isUndefined
114
127
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rhombus-toolkit/type-guards",
3
- "version": "2.0.1",
3
+ "version": "3.0.0",
4
4
  "description": "",
5
5
  "repository": {
6
6
  "type": "git",
@@ -24,7 +24,7 @@
24
24
  "keywords": [],
25
25
  "author": "Thomas Butler",
26
26
  "dependencies": {
27
- "@rhombus-toolkit/types": "1.0.1"
27
+ "@rhombus-toolkit/types": "1.0.0"
28
28
  },
29
29
  "devDependencies": {},
30
30
  "publishConfig": {