1.4.6 • Published 10 months ago

typescript-enum v1.4.6

Weekly downloads
-
License
MIT
Repository
-
Last release
10 months ago

typescript-enum

A set of missing helpers to work with TypeScript enums, providing both runtime and compile-time safety. These helpers cover both string enums and numeric enums.

Installation

npm i typescript-enum

Usage

1) enumValues - converts an enum to an iterable list:

import { enumValues } from 'typescript-enum'

enum Color { R, G, B }

console.log(enumValues(Color)) // [0, 1, 2]

2) isEnumValid - checks if a value is a member of the enum:

import { enumValues } from 'typescript-enum'

enum Color { R, G, B }

const maybeColor = 0;
const notColor = 999;
console.log(isEnumValid(maybeColor, Color)); // true
console.log(isEnumValid(notColor, Color)); // false

if (isEnumValid(maybeColor)) {
  // now the type of maybeColor is inferred to Color
}

Use cases

1. You have a list based on enum values.

Before: ❌ The following component should be updated whenever a new member is added to the enum.

enum Permission { Read = 0, Write = 1, Edit = 2 }

const Component = () => {
  return <List>
    {[Permission.Read, Permission.Write, Permission.Edit].map(permission => {
      // Render checkbox to edit permission
    })}
  </List>  
}

❌ The following works only for string enums but won't work for numeric enums because the enum gets transpiled to {"0": "Read", "1": "Write", "2": "Edit", "Read": 0, "Write": 1, "Edit": 2 }. Notice duplicated values.

enum Permission { Read = 0, Write = 1, Edit = 2 }

const Component = () => {
  return <List>
    {Object.entries(Permission).map(permission => {
      // The enum values are duplicated :(
    })}
  </List>  
}

After: ✅ The following component doesn't need to be updated whenever a new member is added to the enum. It also works with both string and numeric enums.

import { enumValues } from 'typescript-enum'

enum Permission { Read = 0, Write = 1, Edit = 2 }

const Component = () => {
  return <List>
    {enumValues(Permission).map(permission => {
      // Render checkbox to edit permission
    })}
  </List>  
}

2. You want to make sure that an unknown value is a member of the enum.

Before: ❌ The following code requires an unsafe type cast.

enum PackageType { Basic, Advanced, Premium }

const packageInput: { type: number } = { type: 0 }

function processPackage(packageType: PackageType) {
  // ...  
}

processPackage(packageInput.type as any)

✅ The following code validates an unknown value both at runtime and compile time.

import { isEnumValid } from './isEnumValid'

enum Package { Basic, Advanced, Premium }

const packageInput: { type: number } = { type: 0 }

function processPackage(packageType: PackageType) {
  // ...  
}

if (!isEnumValid(packageInput.type, Package)) {
    throw new Error()
}

processPackage(packageInput.type)

As you can see, the type inference works correctly now, and the type cast is no longer needed. You can even go further and use an assertion library:

import { isEnumValid } from './isEnumValid'
import { assert } from 'ts-essentials'

enum Package { Basic, Advanced, Premium }

const packageInput: { type: number } = { type: 0 }

function processPackage(packageType: PackageType) {
  // ...  
}

assert(isEnumValid(packageInput.type, Package))
processPackage(packageInput.type) // packageInput.type is inferred to Package
1.4.6

10 months ago

1.4.5

10 months ago

1.4.4

11 months ago

1.4.3

11 months ago

1.4.1

1 year ago

1.4.0

1 year ago

1.3.0

1 year ago

1.2.0

1 year ago

1.1.0

1 year ago

1.0.0

1 year ago