From 5b13eeedda0cd4ff276080e4ce9ee283a16ce7be Mon Sep 17 00:00:00 2001 From: Dave Cohen Date: Sun, 11 Apr 2021 11:38:48 -0500 Subject: [PATCH] Add `getValuesMessage` option for `assertType` --- source/index.ts | 12 +++++++++--- test/test.ts | 21 +++++++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/source/index.ts b/source/index.ts index 37b536f..6e75b7e 100644 --- a/source/index.ts +++ b/source/index.ts @@ -388,9 +388,11 @@ is.any = (predicate: Predicate | Predicate[], ...values: unknown[]): boolean => is.all = (predicate: Predicate, ...values: unknown[]): boolean => predicateOnArray(Array.prototype.every, predicate, values); -const assertType = (condition: boolean, description: string, value: unknown): asserts condition => { +const assertType = (condition: boolean, description: string, value: unknown, options: { getValuesMessage?: () => string } = {}): asserts condition => { if (!condition) { - throw new TypeError(`Expected value which is \`${description}\`, received value of type \`${is(value)}\`.`); + const {getValuesMessage} = options; + const valuesMessage = getValuesMessage ? getValuesMessage() : `received value of type \`${is(value)}\``; + throw new TypeError(`Expected value which is \`${description}\`, ${valuesMessage}.`); } }; @@ -620,7 +622,11 @@ export const assert: Assert = { inRange: (value: number, range: number | number[]): asserts value is number => assertType(is.inRange(value, range), AssertionTypeDescription.inRange, value), // Variadic functions. - any: (predicate: Predicate | Predicate[], ...values: unknown[]): void | never => assertType(is.any(predicate, ...values), AssertionTypeDescription.any, values), + any: (predicate: Predicate | Predicate[], ...values: unknown[]): void | never => { + // Remove duplicate value types using Set. + const getValuesMessage = () => `received values of types ${[...new Set(values.map(value => `\`${is(value)}\``))].join(', ')}`; + return assertType(is.any(predicate, ...values), AssertionTypeDescription.any, values, {getValuesMessage}); + }, all: (predicate: Predicate, ...values: unknown[]): void | never => assertType(is.all(predicate, ...values), AssertionTypeDescription.all, values) }; diff --git a/test/test.ts b/test/test.ts index c5c98cd..84ae578 100644 --- a/test/test.ts +++ b/test/test.ts @@ -1529,6 +1529,27 @@ test('is.any', t => { t.throws(() => { assert.any(is.string); }); + + t.throws(() => { + assert.any(is.string, 1, 2, 3); + }, { + // Removes duplicates: + message: /received values of types `number`./ + }); + + t.throws(() => { + assert.any(is.string, 1, [4]); + }, { + // Lists all types: + message: /received values of types `number`, `Array`./ + }); + + t.throws(() => { + assert.any([is.string, is.nullOrUndefined], 1); + }, { + // Handles array as first argument: + message: /received values of types `number`./ + }); }); test('is.all', t => {