From f8f85516af3c2990628672cfe93d2756fc3ed419 Mon Sep 17 00:00:00 2001 From: Martin Eneqvist Date: Thu, 8 Feb 2024 15:50:45 +0100 Subject: [PATCH] Add `.validDate()` --- readme.md | 14 ++++++++++++++ source/index.ts | 15 +++++++++++++++ test/test.ts | 11 +++++++++++ 3 files changed, 40 insertions(+) diff --git a/readme.md b/readme.md index c59052c..2171c81 100644 --- a/readme.md +++ b/readme.md @@ -574,6 +574,20 @@ is.all(is.string, '🦄', [], 'unicorns'); //=> false ``` +##### .validDate(value) + +Returns `true` if the value is a valid date. + +`Invalid Date`s occur when an invalid value is passed to the `Date` constructor. This can be an invalid date string, a non-numeric value or a number that is outside of the expected range for a date value. + +```js +is.validDate(new Date()); +//=> true + +is.validDate(new Date('unicorn')); +//=> false +``` + ##### .validLength(value) Returns `true` if the value is a safe integer that is greater than or equal to zero. diff --git a/source/index.ts b/source/index.ts index 2ee08d3..8c1d00b 100644 --- a/source/index.ts +++ b/source/index.ts @@ -128,6 +128,7 @@ const assertionTypeDescriptions = [ 'in range', 'predicate returns truthy for any value', 'predicate returns truthy for all values', + 'valid Date', 'valid length', 'whitespace string', ...objectTypeNames, @@ -311,6 +312,7 @@ const is = Object.assign( urlInstance: isUrlInstance, urlSearchParams: isUrlSearchParams, urlString: isUrlString, + validDate: isValidDate, validLength: isValidLength, weakMap: isWeakMap, weakRef: isWeakRef, @@ -760,6 +762,10 @@ export function isUrlString(value: unknown): value is string { } } +export function isValidDate(value: unknown): value is Date { + return isDate(value) && !isNan(Number(value)); +} + export function isValidLength(value: unknown): value is number { return isSafeInteger(value) && value >= 0; } @@ -917,6 +923,7 @@ type Assert = { propertyKey: (value: unknown) => asserts value is PropertyKey; formData: (value: unknown) => asserts value is FormData; urlSearchParams: (value: unknown) => asserts value is URLSearchParams; + validDate: (value: unknown) => asserts value is Date; validLength: (value: unknown) => asserts value is number; whitespaceString: (value: unknown) => asserts value is string; @@ -1022,6 +1029,7 @@ export const assert: Assert = { urlInstance: assertUrlInstance, urlSearchParams: assertUrlSearchParams, urlString: assertUrlString, + validDate: assertValidDate, validLength: assertValidLength, weakMap: assertWeakMap, weakRef: assertWeakRef, @@ -1114,6 +1122,7 @@ const methodTypeMap = { isUrlInstance: 'URL', isUrlSearchParams: 'URLSearchParams', isUrlString: 'string with a URL', + isValidDate: 'valid Date', isValidLength: 'valid length', isWeakMap: 'WeakMap', isWeakRef: 'WeakRef', @@ -1651,6 +1660,12 @@ export function assertUrlString(value: unknown): asserts value is string { } } +export function assertValidDate(value: unknown): asserts value is Date { + if (!isValidDate(value)) { + throw new TypeError(typeErrorMessage('valid Date', value)); + } +} + export function assertValidLength(value: unknown): asserts value is number { if (!isValidLength(value)) { throw new TypeError(typeErrorMessage('valid length', value)); diff --git a/test/test.ts b/test/test.ts index bbf7b57..1b94a01 100644 --- a/test/test.ts +++ b/test/test.ts @@ -2101,6 +2101,17 @@ test('is.urlSearchParams', t => { }); }); +test('is.validDate', t => { + t.true(is.validDate(new Date())); + t.false(is.validDate(new Date('x'))); + t.notThrows(() => { + assert.validDate(new Date()); + }); + t.throws(() => { + assert.validDate(new Date('x')); + }); +}); + test('is.validLength', t => { t.true(is.validLength(1)); t.true(is.validLength(0));