diff --git a/source/index.ts b/source/index.ts index 748cac0..3f3f1e5 100644 --- a/source/index.ts +++ b/source/index.ts @@ -385,9 +385,9 @@ const predicateOnArray = (method: ArrayMethod, predicate: Predicate, values: unk is.any = (predicate: Predicate, ...values: unknown[]): boolean => predicateOnArray(Array.prototype.some, predicate, values); is.all = (predicate: Predicate, ...values: unknown[]): boolean => predicateOnArray(Array.prototype.every, predicate, values); -const assertType = (condition: boolean, description: string): asserts condition => { +const assertType = (condition: boolean, description: string, value: unknown): asserts condition => { if (!condition) { - throw new TypeError(`Expected value which is "${description}".`); + throw new TypeError(`Expected value which is "${description}", received value of type ${is(value)}.`); } }; @@ -524,90 +524,90 @@ interface Assert { export const assert: Assert = { // Unknowns. - undefined: (value: unknown): asserts value is undefined => assertType(is.undefined(value), TypeName.undefined), - string: (value: unknown): asserts value is string => assertType(is.string(value), TypeName.string), - number: (value: unknown): asserts value is number => assertType(is.number(value), TypeName.number), - bigint: (value: unknown): asserts value is bigint => assertType(is.bigint(value), TypeName.bigint), + undefined: (value: unknown): asserts value is undefined => assertType(is.undefined(value), TypeName.undefined, value), + string: (value: unknown): asserts value is string => assertType(is.string(value), TypeName.string, value), + number: (value: unknown): asserts value is number => assertType(is.number(value), TypeName.number, value), + bigint: (value: unknown): asserts value is bigint => assertType(is.bigint(value), TypeName.bigint, value), // eslint-disable-next-line @typescript-eslint/ban-types - function_: (value: unknown): asserts value is Function => assertType(is.function_(value), TypeName.Function), - null_: (value: unknown): asserts value is null => assertType(is.null_(value), TypeName.null), - class_: (value: unknown): asserts value is Class => assertType(is.class_(value), AssertionTypeDescription.class_), - boolean: (value: unknown): asserts value is boolean => assertType(is.boolean(value), TypeName.boolean), - symbol: (value: unknown): asserts value is symbol => assertType(is.symbol(value), TypeName.symbol), - numericString: (value: unknown): asserts value is string => assertType(is.numericString(value), AssertionTypeDescription.numericString), - array: (value: unknown): asserts value is T[] => assertType(is.array(value), TypeName.Array), - buffer: (value: unknown): asserts value is Buffer => assertType(is.buffer(value), TypeName.Buffer), - nullOrUndefined: (value: unknown): asserts value is null | undefined => assertType(is.nullOrUndefined(value), AssertionTypeDescription.nullOrUndefined), - object: (value: unknown): asserts value is Record => assertType(is.object(value), TypeName.Object), - iterable: (value: unknown): asserts value is Iterable => assertType(is.iterable(value), AssertionTypeDescription.iterable), - asyncIterable: (value: unknown): asserts value is AsyncIterable => assertType(is.asyncIterable(value), AssertionTypeDescription.asyncIterable), - generator: (value: unknown): asserts value is Generator => assertType(is.generator(value), TypeName.Generator), - nativePromise: (value: unknown): asserts value is Promise => assertType(is.nativePromise(value), AssertionTypeDescription.nativePromise), - promise: (value: unknown): asserts value is Promise => assertType(is.promise(value), TypeName.Promise), - generatorFunction: (value: unknown): asserts value is GeneratorFunction => assertType(is.generatorFunction(value), TypeName.GeneratorFunction), + function_: (value: unknown): asserts value is Function => assertType(is.function_(value), TypeName.Function, value), + null_: (value: unknown): asserts value is null => assertType(is.null_(value), TypeName.null, value), + class_: (value: unknown): asserts value is Class => assertType(is.class_(value), AssertionTypeDescription.class_, value), + boolean: (value: unknown): asserts value is boolean => assertType(is.boolean(value), TypeName.boolean, value), + symbol: (value: unknown): asserts value is symbol => assertType(is.symbol(value), TypeName.symbol, value), + numericString: (value: unknown): asserts value is string => assertType(is.numericString(value), AssertionTypeDescription.numericString, value), + array: (value: unknown): asserts value is T[] => assertType(is.array(value), TypeName.Array, value), + buffer: (value: unknown): asserts value is Buffer => assertType(is.buffer(value), TypeName.Buffer, value), + nullOrUndefined: (value: unknown): asserts value is null | undefined => assertType(is.nullOrUndefined(value), AssertionTypeDescription.nullOrUndefined, value), + object: (value: unknown): asserts value is Record => assertType(is.object(value), TypeName.Object, value), + iterable: (value: unknown): asserts value is Iterable => assertType(is.iterable(value), AssertionTypeDescription.iterable, value), + asyncIterable: (value: unknown): asserts value is AsyncIterable => assertType(is.asyncIterable(value), AssertionTypeDescription.asyncIterable, value), + generator: (value: unknown): asserts value is Generator => assertType(is.generator(value), TypeName.Generator, value), + nativePromise: (value: unknown): asserts value is Promise => assertType(is.nativePromise(value), AssertionTypeDescription.nativePromise, value), + promise: (value: unknown): asserts value is Promise => assertType(is.promise(value), TypeName.Promise, value), + generatorFunction: (value: unknown): asserts value is GeneratorFunction => assertType(is.generatorFunction(value), TypeName.GeneratorFunction, value), // eslint-disable-next-line @typescript-eslint/ban-types - asyncFunction: (value: unknown): asserts value is Function => assertType(is.asyncFunction(value), TypeName.AsyncFunction), + asyncFunction: (value: unknown): asserts value is Function => assertType(is.asyncFunction(value), TypeName.AsyncFunction, value), // eslint-disable-next-line @typescript-eslint/ban-types - boundFunction: (value: unknown): asserts value is Function => assertType(is.boundFunction(value), TypeName.Function), - regExp: (value: unknown): asserts value is RegExp => assertType(is.regExp(value), TypeName.RegExp), - date: (value: unknown): asserts value is Date => assertType(is.date(value), TypeName.Date), - error: (value: unknown): asserts value is Error => assertType(is.error(value), TypeName.Error), - map: (value: unknown): asserts value is Map => assertType(is.map(value), TypeName.Map), - set: (value: unknown): asserts value is Set => assertType(is.set(value), TypeName.Set), - weakMap: (value: unknown): asserts value is WeakMap => assertType(is.weakMap(value), TypeName.WeakMap), - weakSet: (value: unknown): asserts value is WeakSet => assertType(is.weakSet(value), TypeName.WeakSet), - int8Array: (value: unknown): asserts value is Int8Array => assertType(is.int8Array(value), TypeName.Int8Array), - uint8Array: (value: unknown): asserts value is Uint8Array => assertType(is.uint8Array(value), TypeName.Uint8Array), - uint8ClampedArray: (value: unknown): asserts value is Uint8ClampedArray => assertType(is.uint8ClampedArray(value), TypeName.Uint8ClampedArray), - int16Array: (value: unknown): asserts value is Int16Array => assertType(is.int16Array(value), TypeName.Int16Array), - uint16Array: (value: unknown): asserts value is Uint16Array => assertType(is.uint16Array(value), TypeName.Uint16Array), - int32Array: (value: unknown): asserts value is Int32Array => assertType(is.int32Array(value), TypeName.Int32Array), - uint32Array: (value: unknown): asserts value is Uint32Array => assertType(is.uint32Array(value), TypeName.Uint32Array), - float32Array: (value: unknown): asserts value is Float32Array => assertType(is.float32Array(value), TypeName.Float32Array), - float64Array: (value: unknown): asserts value is Float64Array => assertType(is.float64Array(value), TypeName.Float64Array), - bigInt64Array: (value: unknown): asserts value is BigInt64Array => assertType(is.bigInt64Array(value), TypeName.BigInt64Array), - bigUint64Array: (value: unknown): asserts value is BigUint64Array => assertType(is.bigUint64Array(value), TypeName.BigUint64Array), - arrayBuffer: (value: unknown): asserts value is ArrayBuffer => assertType(is.arrayBuffer(value), TypeName.ArrayBuffer), - sharedArrayBuffer: (value: unknown): asserts value is SharedArrayBuffer => assertType(is.sharedArrayBuffer(value), TypeName.SharedArrayBuffer), - dataView: (value: unknown): asserts value is DataView => assertType(is.dataView(value), TypeName.DataView), - urlInstance: (value: unknown): asserts value is URL => assertType(is.urlInstance(value), TypeName.URL), - urlString: (value: unknown): asserts value is string => assertType(is.urlString(value), AssertionTypeDescription.urlString), - truthy: (value: unknown): asserts value is unknown => assertType(is.truthy(value), AssertionTypeDescription.truthy), - falsy: (value: unknown): asserts value is unknown => assertType(is.falsy(value), AssertionTypeDescription.falsy), - nan: (value: unknown): asserts value is unknown => assertType(is.nan(value), AssertionTypeDescription.nan), - primitive: (value: unknown): asserts value is unknown => assertType(is.primitive(value), AssertionTypeDescription.primitive), - integer: (value: unknown): asserts value is number => assertType(is.integer(value), AssertionTypeDescription.integer), - safeInteger: (value: unknown): asserts value is number => assertType(is.safeInteger(value), AssertionTypeDescription.safeInteger), - plainObject: (value: unknown): asserts value is {[key: string]: unknown} => assertType(is.plainObject(value), AssertionTypeDescription.plainObject), - typedArray: (value: unknown): asserts value is TypedArray => assertType(is.typedArray(value), AssertionTypeDescription.typedArray), - arrayLike: (value: unknown): asserts value is ArrayLike => assertType(is.arrayLike(value), AssertionTypeDescription.arrayLike), - domElement: (value: unknown): asserts value is Element => assertType(is.domElement(value), AssertionTypeDescription.domElement), - observable: (value: unknown): asserts value is ObservableLike => assertType(is.observable(value), TypeName.Observable), - nodeStream: (value: unknown): asserts value is NodeStream => assertType(is.nodeStream(value), AssertionTypeDescription.nodeStream), - infinite: (value: unknown): asserts value is number => assertType(is.infinite(value), AssertionTypeDescription.infinite), - emptyArray: (value: unknown): asserts value is never[] => assertType(is.emptyArray(value), AssertionTypeDescription.emptyArray), - nonEmptyArray: (value: unknown): asserts value is unknown[] => assertType(is.nonEmptyArray(value), AssertionTypeDescription.nonEmptyArray), - emptyString: (value: unknown): asserts value is '' => assertType(is.emptyString(value), AssertionTypeDescription.emptyString), - nonEmptyString: (value: unknown): asserts value is string => assertType(is.nonEmptyString(value), AssertionTypeDescription.nonEmptyString), - emptyStringOrWhitespace: (value: unknown): asserts value is string => assertType(is.emptyStringOrWhitespace(value), AssertionTypeDescription.emptyStringOrWhitespace), - emptyObject: (value: unknown): asserts value is {[key: string]: never} => assertType(is.emptyObject(value), AssertionTypeDescription.emptyObject), - nonEmptyObject: (value: unknown): asserts value is {[key: string]: unknown} => assertType(is.nonEmptyObject(value), AssertionTypeDescription.nonEmptyObject), - emptySet: (value: unknown): asserts value is Set => assertType(is.emptySet(value), AssertionTypeDescription.emptySet), - nonEmptySet: (value: unknown): asserts value is Set => assertType(is.nonEmptySet(value), AssertionTypeDescription.nonEmptySet), - emptyMap: (value: unknown): asserts value is Map => assertType(is.emptyMap(value), AssertionTypeDescription.emptyMap), - nonEmptyMap: (value: unknown): asserts value is Map => assertType(is.nonEmptyMap(value), AssertionTypeDescription.nonEmptyMap), + boundFunction: (value: unknown): asserts value is Function => assertType(is.boundFunction(value), TypeName.Function, value), + regExp: (value: unknown): asserts value is RegExp => assertType(is.regExp(value), TypeName.RegExp, value), + date: (value: unknown): asserts value is Date => assertType(is.date(value), TypeName.Date, value), + error: (value: unknown): asserts value is Error => assertType(is.error(value), TypeName.Error, value), + map: (value: unknown): asserts value is Map => assertType(is.map(value), TypeName.Map, value), + set: (value: unknown): asserts value is Set => assertType(is.set(value), TypeName.Set, value), + weakMap: (value: unknown): asserts value is WeakMap => assertType(is.weakMap(value), TypeName.WeakMap, value), + weakSet: (value: unknown): asserts value is WeakSet => assertType(is.weakSet(value), TypeName.WeakSet, value), + int8Array: (value: unknown): asserts value is Int8Array => assertType(is.int8Array(value), TypeName.Int8Array, value), + uint8Array: (value: unknown): asserts value is Uint8Array => assertType(is.uint8Array(value), TypeName.Uint8Array, value), + uint8ClampedArray: (value: unknown): asserts value is Uint8ClampedArray => assertType(is.uint8ClampedArray(value), TypeName.Uint8ClampedArray, value), + int16Array: (value: unknown): asserts value is Int16Array => assertType(is.int16Array(value), TypeName.Int16Array, value), + uint16Array: (value: unknown): asserts value is Uint16Array => assertType(is.uint16Array(value), TypeName.Uint16Array, value), + int32Array: (value: unknown): asserts value is Int32Array => assertType(is.int32Array(value), TypeName.Int32Array, value), + uint32Array: (value: unknown): asserts value is Uint32Array => assertType(is.uint32Array(value), TypeName.Uint32Array, value), + float32Array: (value: unknown): asserts value is Float32Array => assertType(is.float32Array(value), TypeName.Float32Array, value), + float64Array: (value: unknown): asserts value is Float64Array => assertType(is.float64Array(value), TypeName.Float64Array, value), + bigInt64Array: (value: unknown): asserts value is BigInt64Array => assertType(is.bigInt64Array(value), TypeName.BigInt64Array, value), + bigUint64Array: (value: unknown): asserts value is BigUint64Array => assertType(is.bigUint64Array(value), TypeName.BigUint64Array, value), + arrayBuffer: (value: unknown): asserts value is ArrayBuffer => assertType(is.arrayBuffer(value), TypeName.ArrayBuffer, value), + sharedArrayBuffer: (value: unknown): asserts value is SharedArrayBuffer => assertType(is.sharedArrayBuffer(value), TypeName.SharedArrayBuffer, value), + dataView: (value: unknown): asserts value is DataView => assertType(is.dataView(value), TypeName.DataView, value), + urlInstance: (value: unknown): asserts value is URL => assertType(is.urlInstance(value), TypeName.URL, value), + urlString: (value: unknown): asserts value is string => assertType(is.urlString(value), AssertionTypeDescription.urlString, value), + truthy: (value: unknown): asserts value is unknown => assertType(is.truthy(value), AssertionTypeDescription.truthy, value), + falsy: (value: unknown): asserts value is unknown => assertType(is.falsy(value), AssertionTypeDescription.falsy, value), + nan: (value: unknown): asserts value is unknown => assertType(is.nan(value), AssertionTypeDescription.nan, value), + primitive: (value: unknown): asserts value is unknown => assertType(is.primitive(value), AssertionTypeDescription.primitive, value), + integer: (value: unknown): asserts value is number => assertType(is.integer(value), AssertionTypeDescription.integer, value), + safeInteger: (value: unknown): asserts value is number => assertType(is.safeInteger(value), AssertionTypeDescription.safeInteger, value), + plainObject: (value: unknown): asserts value is {[key: string]: unknown} => assertType(is.plainObject(value), AssertionTypeDescription.plainObject, value), + typedArray: (value: unknown): asserts value is TypedArray => assertType(is.typedArray(value), AssertionTypeDescription.typedArray, value), + arrayLike: (value: unknown): asserts value is ArrayLike => assertType(is.arrayLike(value), AssertionTypeDescription.arrayLike, value), + domElement: (value: unknown): asserts value is Element => assertType(is.domElement(value), AssertionTypeDescription.domElement, value), + observable: (value: unknown): asserts value is ObservableLike => assertType(is.observable(value), TypeName.Observable, value), + nodeStream: (value: unknown): asserts value is NodeStream => assertType(is.nodeStream(value), AssertionTypeDescription.nodeStream, value), + infinite: (value: unknown): asserts value is number => assertType(is.infinite(value), AssertionTypeDescription.infinite, value), + emptyArray: (value: unknown): asserts value is never[] => assertType(is.emptyArray(value), AssertionTypeDescription.emptyArray, value), + nonEmptyArray: (value: unknown): asserts value is unknown[] => assertType(is.nonEmptyArray(value), AssertionTypeDescription.nonEmptyArray, value), + emptyString: (value: unknown): asserts value is '' => assertType(is.emptyString(value), AssertionTypeDescription.emptyString, value), + nonEmptyString: (value: unknown): asserts value is string => assertType(is.nonEmptyString(value), AssertionTypeDescription.nonEmptyString, value), + emptyStringOrWhitespace: (value: unknown): asserts value is string => assertType(is.emptyStringOrWhitespace(value), AssertionTypeDescription.emptyStringOrWhitespace, value), + emptyObject: (value: unknown): asserts value is {[key: string]: never} => assertType(is.emptyObject(value), AssertionTypeDescription.emptyObject, value), + nonEmptyObject: (value: unknown): asserts value is {[key: string]: unknown} => assertType(is.nonEmptyObject(value), AssertionTypeDescription.nonEmptyObject, value), + emptySet: (value: unknown): asserts value is Set => assertType(is.emptySet(value), AssertionTypeDescription.emptySet, value), + nonEmptySet: (value: unknown): asserts value is Set => assertType(is.nonEmptySet(value), AssertionTypeDescription.nonEmptySet, value), + emptyMap: (value: unknown): asserts value is Map => assertType(is.emptyMap(value), AssertionTypeDescription.emptyMap, value), + nonEmptyMap: (value: unknown): asserts value is Map => assertType(is.nonEmptyMap(value), AssertionTypeDescription.nonEmptyMap, value), // Numbers. - evenInteger: (value: number): asserts value is number => assertType(is.evenInteger(value), AssertionTypeDescription.evenInteger), - oddInteger: (value: number): asserts value is number => assertType(is.oddInteger(value), AssertionTypeDescription.oddInteger), + evenInteger: (value: number): asserts value is number => assertType(is.evenInteger(value), AssertionTypeDescription.evenInteger, value), + oddInteger: (value: number): asserts value is number => assertType(is.oddInteger(value), AssertionTypeDescription.oddInteger, value), // Two arguments. - directInstanceOf: (instance: unknown, class_: Class): asserts instance is T => assertType(is.directInstanceOf(instance, class_), AssertionTypeDescription.directInstanceOf), - inRange: (value: number, range: number | number[]): asserts value is number => assertType(is.inRange(value, range), AssertionTypeDescription.inRange), + directInstanceOf: (instance: unknown, class_: Class): asserts instance is T => assertType(is.directInstanceOf(instance, class_), AssertionTypeDescription.directInstanceOf, instance), + inRange: (value: number, range: number | number[]): asserts value is number => assertType(is.inRange(value, range), AssertionTypeDescription.inRange, value), // Variadic functions. - any: (predicate: Predicate, ...values: unknown[]): void | never => assertType(is.any(predicate, ...values), AssertionTypeDescription.any), - all: (predicate: Predicate, ...values: unknown[]): void | never => assertType(is.all(predicate, ...values), AssertionTypeDescription.all) + any: (predicate: Predicate, ...values: unknown[]): void | never => assertType(is.any(predicate, ...values), AssertionTypeDescription.any, values), + all: (predicate: Predicate, ...values: unknown[]): void | never => assertType(is.all(predicate, ...values), AssertionTypeDescription.all, values) }; // Some few keywords are reserved, but we'll populate them for Node.js users diff --git a/test/test.ts b/test/test.ts index a046699..6e6c4be 100644 --- a/test/test.ts +++ b/test/test.ts @@ -25,8 +25,8 @@ interface Test { is(value: unknown): boolean; } -const invertAssertThrow = (description: string, fn: () => void | never): void | never => { - const expectedAssertErrorMessage = `Expected value which is "${description}".`; +const invertAssertThrow = (description: string, fn: () => void | never, value: unknown): void | never => { + const expectedAssertErrorMessage = `Expected value which is "${description}", received value of type ${is(value)}.`; try { fn(); @@ -481,7 +481,7 @@ const types = new Map([ }], ['non-domElements', { is: value => !is.domElement(value), - assert: (value: unknown) => invertAssertThrow(AssertionTypeDescription.domElement, () => assert.domElement(value)), + assert: (value: unknown) => invertAssertThrow(AssertionTypeDescription.domElement, () => assert.domElement(value), value), fixtures: [ document.createTextNode('data'), document.createProcessingInstruction('xml-stylesheet', 'href="mycss.css" type="text/css"'), @@ -556,7 +556,7 @@ const testType = (t: ExecutionContext, type: string, exclude?: string[]) => { for (const fixture of fixtures) { assertIs(testIs(fixture), `Value: ${inspect(fixture)}`); const valueType = JSON.stringify(typeDescription ? typeDescription : typename); - assertAsserts(() => testAssert(fixture), `Expected value which is ${valueType}.`); + assertAsserts(() => testAssert(fixture), `Expected value which is ${valueType}, received value of type ${is(fixture)}.`); if (isTypeUnderTest && typename) { t.is(is(fixture), typename);