-
-
Notifications
You must be signed in to change notification settings - Fork 31
/
typeOfArguments.js
51 lines (48 loc) · 2.54 KB
/
typeOfArguments.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/**
* {@link TypeOfArguments} validates the arguments' types passed to a function.
*
* It's functionality was inspired by the typeof-arguments npm package (https://www.npmjs.com/package/typeof-arguments).
* @private
*/
class TypeOfArguments {
constructor (givenArray, expectedArray) {
if (!(givenArray instanceof Array)) throw new TypeError('TypeOfArguments: The [0] argument must be the given arguments array.');
if (!(expectedArray instanceof Array)) throw new TypeError('TypeOfArguments: The [1] argument must be the expected argument types Array');
for (let i = 0; i < expectedArray.length; i++) {
const givenArgument = givenArray[i];
const actualType = this._getActualType(givenArgument);
let actualClass;
if (givenArgument !== undefined && givenArgument !== null && givenArgument.constructor && givenArgument.constructor.name) actualClass = givenArgument.constructor.name.toString();
const expectedTypes = this._getExpectedTypes(expectedArray[i]);
let matchesType = false;
for (const element of expectedTypes) {
if (actualType === element) matchesType = true;
if (actualClass !== undefined && actualClass === element) matchesType = true;
if (element === 'null' && givenArgument === null) matchesType = true;
if (matchesType === true) break;
}
if (matchesType !== true) throw new TypeError(`Invalid argument [${i}]. An argument of type "${actualType}" ${actualClass !== undefined ? `and class "${actualClass}"` : ''} has been passed, while an argument matching expression "${expectedArray[i]}" is expected."`);
}
}
_getActualType (value) {
return typeof value;
}
_getExpectedTypes (expected) {
return expected.split('|');
}
}
/**
* {@link TypeOfArguments} validates the arguments' types passed to a function.
*
* A type expression accepts the following:
* - primitive types (`string`, `number`, `bigint`,`boolean`, `symbol`, `undefined`, `null`)
* - `object`
* - classnames (retrieved by getting constructor.name) (e.g. `Item`)
* Type expressions are case-sensitive, it is possible to allow multiple types by using the `|` symbol.
*
* @private
* @param {Array} givenArray Array of the passed in arguments
* @param {Array} expectedArray Array of the expected argument types. The index should match the index of the passed in argument. Each element is a type expression and defines the required type of the matching argument.
* @returns {TypeOfArguments}
*/
module.exports = (givenArray, expectedArray) => new TypeOfArguments(givenArray, expectedArray);