Skip to content

Commit 41f230d

Browse files
committed
update readme, add .of() (untested)
1 parent d25f911 commit 41f230d

File tree

2 files changed

+69
-131
lines changed

2 files changed

+69
-131
lines changed

README.md

Lines changed: 55 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -8,140 +8,68 @@ See the [test page](https://wizard04wsu.github.io/javascript-type-testing/test/t
88
---
99

1010

11-
## Type Names
12-
13-
This module uses an expanded set of type names that make no distinction between primitive values and objects.
14-
For example, `5` and `new Number(5)` are both of type "number".
15-
16-
| Type Name | Primitive Values | Instances Of Classes
17-
| - | - | -
18-
| defined | any value (not undefined) | `Object`
19-
| **undefined** | undefined |
20-
| primitive | not an instance of `Object` |
21-
| **object** | | `Object`
22-
| objectish | `null` | `Object`
23-
| **null** | `null` |
24-
| nullish | undefined, `null` |
25-
| **boolean** | `false`, `true` |
26-
| false | `false` |
27-
| true | `true` |
28-
| falsy | undefined, `null`, `false`, `0n`, `NaN`, `0`, `""` |
29-
| truthy | values that are not _falsy_ | `Object`
30-
| **symbol** | a `Symbol` |
31-
| **bigint** | `0n`, `5n` |
32-
| numberish | `0`, `5`, `Infinity`, `NaN` | `Number`
33-
| **nan** | `NaN` | `Number` instances with value `NaN`
34-
| **number** | `0`, `5`, `Infinity` | `Number` excluding instances with value `NaN`
35-
| real | `0`, `5` | `Number` instances for real numbers
36-
| infinite | `Infinity` | `Number` instances for infinite numbers
37-
| **string** | `""`, `"foo"` | `String`
38-
| **array** | `[]`, `[1,2]` | `Array`
39-
| **map** | | `Map`
40-
| **set** | | `Set`
41-
| **weakmap** | | `WeakMap`
42-
| **weakset** | | `WeakSet`
43-
| empty | `[]` | `String` or `Array` of length == 0, `Map` or `Set` of size == 0
44-
| nonempty | values that are not _empty_ | instances that are not _empty_
45-
| **date** | | `Date`
46-
| **error** | | `Error`
47-
| **function** | | `Function`, `function(){}`, `()=>{}`
48-
| **promise** | | `Promise`
49-
| **regex** | | `Regex`, `/foo/`
50-
51-
52-
## Determine a Type
53-
54-
The **is()** function returns an object describing the type of its argument.
11+
This module uses an expanded set of type names and related descriptors to simplify common tests of values.
12+
Basic types do not distinguish between primitives and objects, but descriptors _primitive_ or _object_
13+
can be used to determine that aspect.
14+
For example, `5` and `new Number(5)` are both _number_, but `5` is _primitive_ and `new Number(5)` is _object_.
5515

56-
Syntax:
57-
> **is**(_value_)
58-
59-
Returned object:
60-
| Property | Description
61-
| - | -
62-
| .**type** | The type name used by this module.
63-
| .**typeof** | The value returned by the `typeof` operator.
64-
| .**toStringTag** | The name used by `Object.prototype.toString()`. `undefined` for primitives.
65-
| .**constructorName** | The name of the argument's constructor. `undefined` for primitives.
66-
| .**isObject** | True if the value is an object.
67-
| .**isPrimitive** | True if the value is a primitive.
68-
69-
70-
## Type Testing
71-
72-
Each of the type-testing methods return a boolean indicating if the argument is of that type.
16+
The **is()** function returns an **IsType** object describing its argument.
7317

7418
Syntax:
75-
> is._typeTester_(_value_)
76-
77-
### Basics
78-
79-
| Method | Tests for
80-
| - | -
81-
| is.**function**() | instance of `Function`
82-
| is.**object**() | instance of `Object`
83-
| is.**primitive**() | primitives
84-
| is.**null**() | `null`
85-
| is.**nullish**() | `undefined`, `null`
86-
| is.**undefined**() | `undefined`
87-
| is.**defined**() | not `undefined`
88-
89-
### Booleans
19+
> **is**(_value_)
9020
91-
| Method | Tests for
92-
| - | -
93-
| is.**boolean**() | `false`, `true`, instance of `Boolean`
94-
| is.**falsy**() | `false`, `undefined`, `null`, `NaN`, `0`, `-0`, `0n`, `""`, [`document.all`](https://developer.mozilla.org/en-US/docs/Web/API/Document/all#conversion_to_boolean)
95-
| is.**truthy**() | not falsy
9621

97-
### Numbers
22+
## IsType Object
9823

99-
| Method | Tests for
24+
| Member | Description
10025
| - | -
101-
| is.**bigint**() | _bigint_ primitive
102-
| is.**date**() | instance of `Date`
103-
| is.**numberish**() | _number_ primitive, instance of `Number`
104-
105-
_Numberish_ values can be more explicitly tested using the following methods:
26+
| .type | The type of _value_ (using this module's type names).
27+
| .of(_class_) | Tests if _value_ was an instance of _class_.
28+
| .all(_...descriptors)_ | Takes a list of descriptor names as arguments. Returns `true` if **all** of them applied to _value_.
29+
| .any(_...descriptors_) | Takes a list of descriptor names as arguments. Returns `true` if **any** of them applied to _value_.
30+
| \[[_descriptor_](#type-names-and-related-descriptors)\] | Descriptors are listed in the table below. Each descriptor property is a boolean that is `true` if it applied to _value_.
31+
32+
Enumerable properties of the **is** function are string values of the name of each descriptor. These can be used
33+
in the `.all()` and `.any()` methods instead of string literals.
34+
For example, `is(_value_).all("number", "object")` is equivalent to `is(_value_).all(is.number, is.object)`.
35+
36+
37+
## Type Names and Related Descriptors
38+
39+
| Descriptor | Type Name | Primitive Values | Instances Of Classes
40+
| - | - | - | -
41+
| defined | | not undefined | `Object`
42+
| **undefined** | yes | undefined |
43+
| primitive | | not an instance of `Object` |
44+
| **object** | yes | | `Object`
45+
| objectish | | `null` | `Object`
46+
| **null** | yes | `null` |
47+
| nullish | | undefined, `null` |
48+
| **boolean** | yes | `false`, `true` |
49+
| false | | `false` |
50+
| true | | `true` |
51+
| falsy | | undefined, `null`, `false`, `0n`, `NaN`, `0`, `""` |
52+
| truthy | | not _falsy_ | `Object`
53+
| **symbol** | yes | a `Symbol` |
54+
| **bigint** | yes | `0n`, `5n` |
55+
| numberish | | `0`, `5`, `Infinity`, `NaN` | `Number`
56+
| **nan** | yes | `NaN` | `Number` with value `NaN`
57+
| **number** | yes | `0`, `5`, `Infinity` | `Number` excluding those with value `NaN`
58+
| real | | `0`, `5` | `Number` with a real number value
59+
| infinite | | `Infinity` | `Number` with an infinite value
60+
| **string** | yes | `""`, `"foo"` | `String`
61+
| **array** | yes | `[]`, `[1,2]` | `Array`
62+
| **map** | yes | | `Map`
63+
| **set** | yes | | `Set`
64+
| **weakmap** | yes | | `WeakMap`
65+
| **weakset** | yes | | `WeakSet`
66+
| empty | | `""`, `[]` | `String` or `Array` of length == 0, `Map` or `Set` of size == 0
67+
| nonempty | | not _empty_ | `String`, `Array`, `Map`, or `Set` that is not _empty_
68+
| **date** | yes | | `Date`
69+
| **error** | yes | | `Error`
70+
| **function** | yes | | `Function`, `function(){}`, `()=>{}`
71+
| **promise** | yes | | `Promise`
72+
| **regex** | yes | | `Regex`, `/foo/`
10673

107-
| Method | Tests for
108-
| - | -
109-
| is.**real**() | real numbers
110-
| is.**infinite**() | `Infinity`, `-Infinity`
111-
| is.**number**() | real numbers, `Infinity`, `-Infinity`
112-
| is.**nan**() | `NaN`
11374

11475
Note that JavaScript doesn't always treat mathematical expressions of undefined or indeterminate form as you might expect. For example, `1/0` is an undefined form, but JavaScript evaluates it as `Infinity`.
115-
116-
### Text
117-
118-
| Method | Tests for
119-
| - | -
120-
| is.**regex**() | instance of `RegExp`
121-
| is.**string**() | _string_ primitive, instance of `String`
122-
123-
### Collections
124-
125-
| Method | Tests for
126-
| - | -
127-
| is.**array**() | instance of `Array`
128-
| is.**map**() | instance of `Map`
129-
| is.**set**() | instance of `Set`
130-
| is.**weakmap**() | instance of `WeakMap`
131-
| is.**weakset**() | instance of `WeakSet`
132-
133-
### Other Common Types
134-
135-
| Method | Tests for
136-
| - | -
137-
| is.**error**() | instance of `Error`
138-
| is.**promise**() | instance of `Promise`
139-
| is.**symbol**() | _symbol_ primitive
140-
141-
142-
## Additional Methods
143-
144-
| Method | Description
145-
| - | -
146-
| is.**empty**(_value_) | Tests for an empty _string_ primitive or if an object's `.length` or `.size` property equals zero.
147-
| is.**of**(_value_, _class_) | Tests if _value_ is an instance of _class_. (Same as using the `instanceof` operator.)

isType.mjs.js

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,16 +108,23 @@ class TypeTest {
108108
}
109109
}
110110

111-
class Is extends TypeTest {
111+
class IsType extends TypeTest {
112+
113+
#valueConstructor;
112114

113115
constructor(value){
114116
super(value);
117+
if(value instanceof Object) this.#valueConstructor = value.constructor;
115118
}
116119

117120
get type(){
118121
return this.toString();
119122
}
120123

124+
of(constructor){
125+
return this.#valueConstructor && (this.#valueConstructor === constructor || this.#valueConstructor.prototype instanceof constructor);
126+
}
127+
121128
all(...propNames){
122129
return propNames.every(propName=>this[propName]);
123130
}
@@ -130,15 +137,18 @@ class Is extends TypeTest {
130137
/**
131138
* Determine the type of a value. The returned object includes boolean properties to quickly test against specific types or for specific states (e.g., 'empty').
132139
* @param {*} value - The value to be tested.
133-
* @returns {Is}
140+
* @returns {IsType}
134141
*/
135142
function is(value){
136143

137-
return new Is(value);
144+
return new IsType(value);
138145
}
139146

140147
for(const propName in new TypeTest()){
141-
is[propName] = propName;
148+
Object.defineProperty(is, propName, {
149+
value: propName,
150+
enumerable: true,
151+
});
142152
}
143153

144154
export { is as default };

0 commit comments

Comments
 (0)