ts-enum-util
Advanced tools
Comparing version 0.0.7 to 0.0.8
@@ -32,6 +32,2 @@ "use strict"; | ||
/** | ||
* Set of all values for this enum. | ||
*/ | ||
this.valueSet = new Set(); | ||
/** | ||
* Map of enum value -> enum key. | ||
@@ -48,3 +44,2 @@ * Used for reverse key lookups. | ||
var value = enumObj[key]; | ||
_this.valueSet.add(value); | ||
_this.keysByValueMap.set(value, key); | ||
@@ -136,3 +131,3 @@ }); | ||
EnumWrapper.prototype.values = function () { | ||
return this.valueSet.values(); | ||
return this.keysByValueMap.keys(); | ||
}; | ||
@@ -206,3 +201,3 @@ /** | ||
EnumWrapper.prototype.getKeys = function () { | ||
return Array.from(this.keySet.values()); | ||
return Array.from(this.keys()); | ||
}; | ||
@@ -216,3 +211,3 @@ /** | ||
EnumWrapper.prototype.getValues = function () { | ||
return Array.from(this.valueSet.values()); | ||
return Array.from(this.values()); | ||
}; | ||
@@ -247,3 +242,3 @@ /** | ||
else { | ||
throw new Error("Unexpected key: " + key + ". Expected one of: " + Array.from(this.keySet)); | ||
throw new Error("Unexpected key: " + key + ". Expected one of: " + this.getValues()); | ||
} | ||
@@ -273,3 +268,3 @@ }; | ||
EnumWrapper.prototype.isValue = function (value) { | ||
return value !== undefined && this.valueSet.has(value); | ||
return value !== undefined && this.keysByValueMap.has(value); | ||
}; | ||
@@ -288,3 +283,3 @@ /** | ||
else { | ||
throw new Error("Unexpected value: " + value + ". Expected one of: " + Array.from(this.valueSet)); | ||
throw new Error("Unexpected value: " + value + ". Expected one of: " + this.getValues()); | ||
} | ||
@@ -291,0 +286,0 @@ }; |
@@ -30,6 +30,2 @@ /** | ||
/** | ||
* Set of all values for this enum. | ||
*/ | ||
this.valueSet = new Set(); | ||
/** | ||
* Map of enum value -> enum key. | ||
@@ -46,3 +42,2 @@ * Used for reverse key lookups. | ||
var value = enumObj[key]; | ||
_this.valueSet.add(value); | ||
_this.keysByValueMap.set(value, key); | ||
@@ -134,3 +129,3 @@ }); | ||
EnumWrapper.prototype.values = function () { | ||
return this.valueSet.values(); | ||
return this.keysByValueMap.keys(); | ||
}; | ||
@@ -204,3 +199,3 @@ /** | ||
EnumWrapper.prototype.getKeys = function () { | ||
return Array.from(this.keySet.values()); | ||
return Array.from(this.keys()); | ||
}; | ||
@@ -214,3 +209,3 @@ /** | ||
EnumWrapper.prototype.getValues = function () { | ||
return Array.from(this.valueSet.values()); | ||
return Array.from(this.values()); | ||
}; | ||
@@ -245,3 +240,3 @@ /** | ||
else { | ||
throw new Error("Unexpected key: " + key + ". Expected one of: " + Array.from(this.keySet)); | ||
throw new Error("Unexpected key: " + key + ". Expected one of: " + this.getValues()); | ||
} | ||
@@ -271,3 +266,3 @@ }; | ||
EnumWrapper.prototype.isValue = function (value) { | ||
return value !== undefined && this.valueSet.has(value); | ||
return value !== undefined && this.keysByValueMap.has(value); | ||
}; | ||
@@ -286,3 +281,3 @@ /** | ||
else { | ||
throw new Error("Unexpected value: " + value + ". Expected one of: " + Array.from(this.valueSet)); | ||
throw new Error("Unexpected value: " + value + ". Expected one of: " + this.getValues()); | ||
} | ||
@@ -289,0 +284,0 @@ }; |
@@ -36,6 +36,2 @@ /** | ||
/** | ||
* Set of all values for this enum. | ||
*/ | ||
private readonly valueSet; | ||
/** | ||
* Map of enum value -> enum key. | ||
@@ -42,0 +38,0 @@ * Used for reverse key lookups. |
{ | ||
"name": "ts-enum-util", | ||
"version": "0.0.7", | ||
"version": "0.0.8", | ||
"description": "TypeScript Enum Utilities", | ||
@@ -46,12 +46,12 @@ "repository": { | ||
"devDependencies": { | ||
"@types/jest": "22.1.1", | ||
"@types/node": "9.4.0", | ||
"@types/jest": "22.1.3", | ||
"@types/node": "9.4.6", | ||
"copyfiles": "1.2.0", | ||
"coveralls": "3.0.0", | ||
"jest": "22.1.4", | ||
"jest": "22.3.0", | ||
"npm-run-all": "4.1.2", | ||
"rimraf": "2.6.2", | ||
"ts-jest": "22.0.2", | ||
"ts-jest": "22.0.4", | ||
"tslint": "5.9.1", | ||
"typescript": "^2.7.1" | ||
"typescript": "2.7.2" | ||
}, | ||
@@ -58,0 +58,0 @@ "peerDependencies": { |
197
README.md
@@ -16,2 +16,11 @@ [![npm version](https://img.shields.io/npm/v/ts-enum-util.svg)](https://www.npmjs.com/package/ts-enum-util) | ||
- [Usage Examples](#usage-examples) | ||
- [Basic setup for all examples](#basic-setup-for-all-examples) | ||
- [Get count of enum entries](#get-count-of-enum-entries) | ||
- [Get lists of enum data](#get-lists-of-enum-data) | ||
- [Lookup value by key](#lookup-value-by-key) | ||
- [Reverse lookup key by value](#reverse-lookup-key-by-value) | ||
- [Validate/convert enum keys](#validateconvert-enum-keys) | ||
- [Validate/convert enum values](#validateconvert-enum-values) | ||
- [Iteration and mapping](#iteration-and-mapping) | ||
- [Wrapped enums are directly iterable like a Map!](#wrapped-enums-are-directly-iterable-like-a-map) | ||
- [Requirements](#requirements) | ||
@@ -24,6 +33,8 @@ - [General Concepts](#general-concepts) | ||
- [Caching](#caching) | ||
- [Reference](#reference) | ||
- [API Reference](#api-reference) | ||
- [Terminology](#terminology) | ||
- [$enum](#enum) | ||
- [EnumWrapper](#enumwrapper-1) | ||
- [EnumWrapper.Entry](#enumwrapperentry) | ||
- [EnumWrapper.Iteratee](#enumwrapperiteratee) | ||
- [EnumWrapper.prototype.size](#enumwrapperprototypesize) | ||
@@ -35,5 +46,18 @@ - [EnumWrapper.prototype.get](#enumwrapperprototypeget) | ||
- [EnumWrapper.prototype.entries](#enumwrapperprototypeentries) | ||
- [EnumWrapper.prototype.@@iterator](#enumwrapperprototypeiterator) | ||
- [EnumWrapper.prototype.forEach](#enumwrapperprototypeforeach) | ||
- [EnumWrapper.prototype.map](#enumwrapperprototypemap) | ||
- [EnumWrapper.prototype.getKeys](#enumwrapperprototypegetkeys) | ||
- [EnumWrapper.prototype.getValues](#enumwrapperprototypegetvalues) | ||
- [EnumWrapper.prototype.getEntries](#enumwrapperprototypegetentries) | ||
- [EnumWrapper.prototype.isKey](#enumwrapperprototypeiskey) | ||
- [EnumWrapper.prototype.asKey](#enumwrapperprototypeaskey) | ||
- [EnumWrapper.prototype.asKeyOrDefault](#enumwrapperprototypeaskeyordefault) | ||
- [EnumWrapper.prototype.isValue](#enumwrapperprototypeisvalue) | ||
- [EnumWrapper.prototype.asValue](#enumwrapperprototypeasvalue) | ||
- [EnumWrapper.prototype.asValueOrDefault](#enumwrapperprototypeasvalueordefault) | ||
- [EnumWrapper.prototype.getKey](#enumwrapperprototypegetkey) | ||
- [EnumWrapper.prototype.getKeyOrDefault](#enumwrapperprototypegetkeyordefault) | ||
- [EnumWrapper.prototype.getValue](#enumwrapperprototypegetvalue) | ||
- [EnumWrapper.prototype.getValueOrDefault](#enumwrapperprototypegetvalueordefault) | ||
- [Limitations](#limitations) | ||
@@ -44,3 +68,3 @@ | ||
## What is it? | ||
`ts-enum-util` provides utilities to improve the usefulness of enums. Examples include getting a list of an enum's keys, values, or key/value pairs, reverse lookup of keys by value, run-time validation that a specified value or key is valid for a given enum, and more. | ||
`ts-enum-util` provides utilities to improve the usefulness of enums. Examples include getting a list of an enum's keys, values, or key/value pairs, reverse lookup of keys by value, run-time validation that a specified value or key is valid for a given enum (with corresponding compile-time type guards), and more. All of these utilities are very specifically typed for each enum via generics and type inference. | ||
@@ -55,9 +79,16 @@ ## Quick Start | ||
### Usage Examples | ||
Several small examples `ts-enum-util`'s capabilities to give you a quick overview of what it can do. | ||
Several small examples `ts-enum-util`'s capabilities to give you a quick overview of what it can do, as well as an organized "by example" reference. | ||
Pay special attention to the comments indicating the compile-time type of various results. See [Specific Typing](#specific-typing) for more about data types. | ||
See [API Reference](#api-reference) for more details about method signatures and behaviors. | ||
#### Basic setup for all examples | ||
```ts | ||
// import the $enum helper function | ||
import {$enum} from "ts-enum-util"; | ||
// Example string enum | ||
// (basic numeric enums also supported) | ||
// (enums with a mix of numeric and string values also supported) | ||
enum RGB { | ||
@@ -68,3 +99,13 @@ R = "r", | ||
} | ||
``` | ||
#### Get count of enum entries | ||
```ts | ||
// type: number | ||
// value: 3 | ||
const count = $enum(RGB).size; | ||
``` | ||
#### Get lists of enum data | ||
```ts | ||
// type: ("R" | "G" | "B")[] | ||
@@ -78,9 +119,35 @@ // value: ["R", "G", "B"] | ||
// List of key/value pair tuples | ||
// type: ["R" | "G" | "B", RGB][] | ||
// value: [["R", "r"], ["G", "g"], ["B", "b"]] | ||
const entries = $enum(RGB).getEntries(); | ||
``` | ||
#### Lookup value by key | ||
```ts | ||
// type: RGB | ||
// value: "g" | ||
const value1 = $enum(RGB).getValue("G"); | ||
// throws: Error("Unexpected value: blah. Expected one of: R,G,B") | ||
const value2 = $enum(RGB).getValue("blah"); | ||
// type: RGB | undefined | ||
// value: undefined | ||
const value3 = $enum(RGB).getValueOrDefault("blah"); | ||
// type: RGB | ||
// value: "r" | ||
const value4 = $enum(RGB).getValueOrDefault("blah", "R"); | ||
// type: string | ||
// value: "BLAH!" | ||
const value5 = $enum(RGB).getValueOrDefault("blah", "BLAH!"); | ||
``` | ||
#### Reverse lookup key by value | ||
```ts | ||
// type: "R" | "G" | "B" | ||
// value: "G" | ||
const key = $enum(RGB).getKey("g"); | ||
const key1 = $enum(RGB).getKey("g"); | ||
@@ -101,9 +168,7 @@ // throws: Error("Unexpected value: blah. Expected one of: r,g,b") | ||
const key4 = $enum(RGB).getKeyOrDefault("blah", "BLAH!"); | ||
``` | ||
// A wrapped enum is iterable! | ||
for (const [key, value] of $enum(RGB)) { | ||
// type of key: "R" | "G" | "B" | ||
// type of value: RGB | ||
} | ||
#### Validate/convert enum keys | ||
```ts | ||
// Some arbitrary string | ||
declare const str: string; | ||
@@ -119,12 +184,18 @@ | ||
// throws error if 'str' is not a valid key for RGB | ||
const key5 = $enum(RGB).asKey(str); | ||
const key1 = $enum(RGB).asKey(str); | ||
// type: "R" | "G" | "B" | undefined | ||
// value is undefined if 'str' is not a valid key for RGB | ||
const key6 = $enum(RGB).asKeyOrDefault(str); | ||
const key2 = $enum(RGB).asKeyOrDefault(str); | ||
// type: "R" | "G" | "B" | ||
// value is "G" if 'str' is not a valid key for RGB | ||
const key6 = $enum(RGB).asKeyOrDefault(str, "G"); | ||
const key3 = $enum(RGB).asKeyOrDefault(str, "G"); | ||
``` | ||
#### Validate/convert enum values | ||
```ts | ||
// Some arbitrary string | ||
declare const str: string; | ||
// returns true if 'str' is a valid value of RGB | ||
@@ -138,3 +209,3 @@ if($enum(RGB).isValue(str)) { | ||
// throws error if 'str' is not a valid value for RGB | ||
const value = $enum(RGB).asValue(str); | ||
const value1 = $enum(RGB).asValue(str); | ||
@@ -148,3 +219,6 @@ // type: RGB | undefined | ||
const value3 = $enum(RGB).asValueOrDefault(str, RGB.G); | ||
``` | ||
#### Iteration and mapping | ||
```ts | ||
// iterate all entries in the enum | ||
@@ -154,3 +228,3 @@ $enum(RGB).forEach((value, key, rgbRef) => { | ||
// type of key is "R" | "G" | "B" | ||
// rgbRef is a reference to RGB, type is typeof RBG | ||
// rgbRef is a reference to RGB object, type is (typeof RBG) | ||
}); | ||
@@ -163,3 +237,3 @@ | ||
// type of key is "R" | "G" | "B" | ||
// rgbRef is a reference to RGB, type is typeof RBG | ||
// rgbRef is a reference to RGB object, type is (typeof RBG) | ||
return `${key}: ${value}`; | ||
@@ -169,2 +243,18 @@ }); | ||
#### Wrapped enums are directly iterable like a Map! | ||
```ts | ||
for (const [key, value] of $enum(RGB)) { | ||
// type of key: "R" | "G" | "B" | ||
// type of value: RGB | ||
} | ||
for (const key of $enum(RGB).keys()) { | ||
// type of key: "R" | "G" | "B" | ||
} | ||
for (const value of $enum(RGB).values()) { | ||
// type of value: RGB | ||
} | ||
``` | ||
## Requirements | ||
@@ -185,3 +275,3 @@ * *ES6 Features*: The following ES6 features are used by `ts-enum-util`, so they must exist (either natively or via polyfill) in the run-time environment: `Array.from()`, `Map`, `Set`, `Symbol.iterator`. | ||
### Specific Typing | ||
The various methods of `ts-enum-util` are generic and overloaded to ensure that params and results are as specifically-typed as possible. | ||
The various methods of `ts-enum-util` are generic and overloaded to ensure that params and results are as specifically-typed as possible. This is acheived through generics, type inference, and overloading of the `$enum` function signature that is used to obtain an `EnumWrapper` instance for a particular enum. | ||
@@ -194,16 +284,16 @@ For example, when obtaining a key or keys from an `EnumWrapper`, the data type will be a string literal union containing only the specific key names that exist in the enum. | ||
A subset of `EnumWrapper`'s interface overlaps with much of the ES6 `Map` interface. `EnumWrapper` is effectively a read-only `Map` of enum values, keyed by the enum names. The following Map-like features are implemented: | ||
* `size` property. | ||
* `has` and `get` methods. | ||
* `keys`, `values`, and `entries` methods. | ||
* `forEach` method. | ||
* `@@iterator` method (`EnumWrapper` is iterable!). | ||
* [size](#enumwrapperprototypesize) property. | ||
* [has](#enumwrapperprototypehas) and [get](#enumwrapperprototypeget) methods. | ||
* [keys](#enumwrapperprototypekeys), [values](#enumwrapperprototypevalues), and [entries](#enumwrapperprototypeentries) methods. | ||
* [forEach](#enumwrapperprototypeforeach) method. | ||
* [@@iterator](#enumwrapperprototypeiterator) method (`EnumWrapper` is iterable!). | ||
### Caching | ||
By default, `EnumWrapper` instances are cached for quick subsequent retrieval via the [$enum](#enum) function. This makes sense for typical enums. | ||
By default, `EnumWrapper` instances are cached for quick subsequent retrieval via the [$enum](#enum) function. | ||
The reasoning behind this is that enums are static constructs. A given project will have a relatively small finite number of enums that never change during execution. The combination of caching and the simple [$enum](#enum) function allows you to obtain an `EnumWrapper` instance conveniently whenever you need it, without maintaining a reference to it. | ||
The reasoning behind this is that enums are static constructs. A given project will have a relatively small finite number of enums that never change during execution. The combination of caching and the simple [$enum](#enum) function allows you to obtain an `EnumWrapper` instance conveniently whenever you need it, without worrying about maintaining a reference to it. Of course, it's still good practice to store a reference to the `EnumWrapper` within certain code context where you heavily a particular enum's wrapper for readability and to avoid unnecessary cache lookups. | ||
You may want to consider explicitly avoiding caching (via an optional param to `$enum`) if you are using `ts-enum-util` to work with an ad-hoc dynamically generated "enum-like" object. this is useful to avoid cluttering the cache and unnecessarily occupying memory with an `EnumWrapper` that will never be retrieved from the cache. | ||
You should consider explicitly avoiding caching (via an optional param to `$enum`) if you are using `ts-enum-util` to work with an ad-hoc dynamically generated "enum-like" object. This is useful to avoid cluttering the cache and unnecessarily occupying memory with an `EnumWrapper` that will never be retrieved from the cache. | ||
## Reference | ||
## API Reference | ||
!!! WORK IN PROGRESS / INCOMPLETE !!! | ||
@@ -213,2 +303,4 @@ | ||
See [Usage Examples](#usage-examples) if you prefer a "by example" reference. | ||
### Terminology | ||
@@ -235,2 +327,12 @@ | ||
### EnumWrapper.Entry | ||
`type EnumWrapper.Entry = [KeyType, EnumType]` | ||
A generic type alias for a tuple containing a key and value pair, representing a complete "entry" in the enum. | ||
### EnumWrapper.Iteratee | ||
`type EnumWrapper.Iteratee = (value: EnumType, key: KeyType, enumObj: EnumLike) => R` | ||
A generic type alias for a function signature to be used in iteration methods. | ||
### EnumWrapper.prototype.size | ||
@@ -254,4 +356,13 @@ `EnumWrapper.prototype.size: number` | ||
### EnumWrapper.prototype.entries | ||
`EnumWrapper.prototype.entries(): IterableIterator<[KeyType, EnumType]>` | ||
`EnumWrapper.prototype.entries(): IterableIterator<EnumWrapper.Entry>` | ||
### EnumWrapper.prototype.@@iterator | ||
`EnumWrapper.prototype.@@iterator(): IterableIterator<EnumWrapper.Entry>` | ||
### EnumWrapper.prototype.forEach | ||
`EnumWrapper.prototype.forEach(iteratee: EnumWrapper.Iteratee, context?: any): void` | ||
### EnumWrapper.prototype.map | ||
`EnumWrapper.prototype.map<R>(iteratee: EnumWrapper.Iteratee, context?: any): R[]` | ||
### EnumWrapper.prototype.getKeys | ||
@@ -264,6 +375,36 @@ `EnumWrapper.prototype.getKeys(): KeyType[]` | ||
### EnumWrapper.prototype.getEntries | ||
`EnumWrapper.prototype.getEntries(): [KeyType, EnumType][]` | ||
`EnumWrapper.prototype.getEntries(): EnumWrapper.Entry[]` | ||
### EnumWrapper.prototype.isKey | ||
`EnumWrapper.prototype.isKey(key: string): key is KeyType` | ||
### EnumWrapper.prototype.asKey | ||
`EnumWrapper.prototype.asKey(key: string): KeyType` | ||
### EnumWrapper.prototype.asKeyOrDefault | ||
`EnumWrapper.prototype.asKeyOrDefault(key: string, defaultKey?: KeyType | string): KeyType | string | undefined` | ||
### EnumWrapper.prototype.isValue | ||
`EnumWrapper.prototype.isValue(value: ValueType): key is EnumType` | ||
### EnumWrapper.prototype.asValue | ||
`EnumWrapper.prototype.asValue(value: ValueType): EnumType` | ||
### EnumWrapper.prototype.asValueOrDefault | ||
`EnumWrapper.prototype.asValueOrDefault(value: ValueType, defaultValue?: EnumType | ValueType): EnumType | ValueType | undefined` | ||
### EnumWrapper.prototype.getKey | ||
`EnumWrapper.prototype.getKey(value: ValueType): KeyType` | ||
### EnumWrapper.prototype.getKeyOrDefault | ||
`EnumWrapper.prototype.getKeyOrDefault(value: ValueType, defaultKey?: KeyType | string): KeyType | string | undefined` | ||
### EnumWrapper.prototype.getValue | ||
`EnumWrapper.prototype.getValue(key: string): EnumType` | ||
### EnumWrapper.prototype.getValueOrDefault | ||
`EnumWrapper.prototype.getValueOrDefault(key: string, defaultValue?: EnumType | ValueType): EnumType | ValueType | undefined` | ||
## Limitations | ||
Does not work with enums that are merged with a namespace containing values (variables, functions, etc.), or otherwise have any additional properties added to the enum's runtime object. | ||
@@ -41,7 +41,2 @@ /** | ||
/** | ||
* Set of all values for this enum. | ||
*/ | ||
private readonly valueSet = new Set<T[keyof T]>(); | ||
/** | ||
* Map of enum value -> enum key. | ||
@@ -195,3 +190,2 @@ * Used for reverse key lookups. | ||
const value = enumObj[key]; | ||
this.valueSet.add(value); | ||
this.keysByValueMap.set(value, key); | ||
@@ -255,3 +249,3 @@ }); | ||
public values(): IterableIterator<T[keyof T]> { | ||
return this.valueSet.values(); | ||
return this.keysByValueMap.keys(); | ||
} | ||
@@ -330,3 +324,3 @@ | ||
public getKeys(): (keyof T)[] { | ||
return Array.from(this.keySet.values()); | ||
return Array.from(this.keys()); | ||
} | ||
@@ -341,3 +335,3 @@ | ||
public getValues(): T[keyof T][] { | ||
return Array.from(this.valueSet.values()); | ||
return Array.from(this.values()); | ||
} | ||
@@ -374,3 +368,3 @@ | ||
} else { | ||
throw new Error(`Unexpected key: ${key}. Expected one of: ${Array.from(this.keySet)}`); | ||
throw new Error(`Unexpected key: ${key}. Expected one of: ${this.getValues()}`); | ||
} | ||
@@ -433,3 +427,3 @@ } | ||
public isValue(value: V): value is T[keyof T] { | ||
return value !== undefined && this.valueSet.has(value); | ||
return value !== undefined && this.keysByValueMap.has(value); | ||
} | ||
@@ -448,3 +442,3 @@ | ||
} else { | ||
throw new Error(`Unexpected value: ${value}. Expected one of: ${Array.from(this.valueSet)}`); | ||
throw new Error(`Unexpected value: ${value}. Expected one of: ${this.getValues()}`); | ||
} | ||
@@ -451,0 +445,0 @@ } |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
116696
391
1843
1