From a5b4017d5e3baf10eca7844a96e2e133e2ab899e Mon Sep 17 00:00:00 2001 From: Olivier Beaulieu Date: Mon, 17 Jan 2022 00:55:40 -0500 Subject: [PATCH] Add `is.enumCase` and `assert.enumCase` (#150) Co-authored-by: Sindre Sorhus --- readme.md | 19 +++++++++++++++++++ source/index.ts | 3 +++ test/test.ts | 17 +++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/readme.md b/readme.md index f956fcc..b980b42 100644 --- a/readme.md +++ b/readme.md @@ -212,6 +212,25 @@ is.boundFunction(function () {}); ##### .sharedArrayBuffer(value) ##### .dataView(value) +##### .enumCase(value, enum) + +**TypeScript-only** + +Returns `true` if `value` is a member of `enum`. + +```ts +enum Direction { + Ascending = 'ascending', + Descending = 'descending' +} + +is.enumCase('ascending', Direction); +//=> true + +is.enumCase('other', Direction); +//=> false +``` + #### Emptiness ##### .emptyString(value) diff --git a/source/index.ts b/source/index.ts index be9f990..561cfcf 100644 --- a/source/index.ts +++ b/source/index.ts @@ -230,6 +230,7 @@ is.bigUint64Array = isObjectOfType('BigUint64Array'); is.arrayBuffer = isObjectOfType('ArrayBuffer'); is.sharedArrayBuffer = isObjectOfType('SharedArrayBuffer'); is.dataView = isObjectOfType('DataView'); +is.enumCase = (value: unknown, targetEnum: T) => Object.values(targetEnum).includes(value as string); is.directInstanceOf = (instance: unknown, class_: Class): instance is T => Object.getPrototypeOf(instance) === class_.prototype; is.urlInstance = (value: unknown): value is URL => isObjectOfType('URL')(value); @@ -501,6 +502,7 @@ interface Assert { arrayBuffer: (value: unknown) => asserts value is ArrayBuffer; sharedArrayBuffer: (value: unknown) => asserts value is SharedArrayBuffer; dataView: (value: unknown) => asserts value is DataView; + enumCase: (value: unknown, targetEnum: T) => asserts value is T[keyof T]; urlInstance: (value: unknown) => asserts value is URL; urlString: (value: unknown) => asserts value is string; truthy: (value: unknown) => asserts value is unknown; @@ -601,6 +603,7 @@ export const assert: Assert = { arrayBuffer: (value: unknown): asserts value is ArrayBuffer => assertType(is.arrayBuffer(value), 'ArrayBuffer', value), sharedArrayBuffer: (value: unknown): asserts value is SharedArrayBuffer => assertType(is.sharedArrayBuffer(value), 'SharedArrayBuffer', value), dataView: (value: unknown): asserts value is DataView => assertType(is.dataView(value), 'DataView', value), + enumCase: (value: unknown, targetEnum: T): asserts value is T[keyof T] => assertType(is.enumCase(value, targetEnum), 'EnumCase', value), urlInstance: (value: unknown): asserts value is URL => assertType(is.urlInstance(value), '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), diff --git a/test/test.ts b/test/test.ts index 87455db..734fd27 100644 --- a/test/test.ts +++ b/test/test.ts @@ -832,6 +832,23 @@ test('is.dataView', t => { testType(t, 'dataView'); }); +test('is.enumCase', t => { + enum NonNumericalEnum { + Key1 = 'key1', + Key2 = 'key2', + } + + t.true(is.enumCase('key1', NonNumericalEnum)); + t.notThrows(() => { + assert.enumCase('key1', NonNumericalEnum); + }); + + t.false(is.enumCase('invalid', NonNumericalEnum)); + t.throws(() => { + assert.enumCase('invalid', NonNumericalEnum); + }); +}); + test('is.directInstanceOf', t => { const error = new Error(); const errorSubclass = new ErrorSubclassFixture();