npm package: @katis/enum
Description: A modern non-nominative TypeScript enum library
Author: Joni Katajamäki
Latest version: 0.1.0

# @katis/enum

A type-safe, non-nominative enum implementation for TypeScript that provides useful helper methods for working with enum values, labels, and reverse mappings.

## Features

- Type-safe enum creation with full TypeScript support
- Reverse mapping from values to labels
- Set of all enum values and labels
- Value existence checking
- Support for string, number, and symbol values
- Enumerable properties for JSON serialization
- No naming conflicts between enum labels and helper methods

## Installation

```bash
npm install @katis/enum
```

## Usage

### Basic Usage

```typescript
import { Enum } from '@katis/enum';

// Create an enum
const Color = Enum({
  Red: 'RED',
  Green: 'GREEN',
  Blue: 'BLUE'
});

// Use enum values
const color: typeof Color = Color.Red; // Type-safe: 'RED'
console.log(color); // 'RED'

// Check if a value exists
if (Enum.contains(Color, 'RED')) {
  // Value exists in the enum
}

// Get all values
const allColors = Enum.values(Color); // Set { 'RED', 'GREEN', 'BLUE' }

// Get all labels
const allLabels = Enum.labels(Color); // Set { 'Red', 'Green', 'Blue' }

// Get label for a value
const label = Enum.reversed(Color).get('RED'); // 'Red'

// Join multiple enums
const ExtendedColor = Enum({
  ...Color,
  Yellow: 'YELLOW',
  Purple: 'PURPLE'
});
// ExtendedColor now has all colors from Color plus Yellow and Purple
```

### With Different Value Types

```typescript
// Number values
const Numbers = Enum({
  One: 1,
  Two: 2,
  Three: 3
});

// Symbol values
const Symbols = Enum({
  One: Symbol('one'),
  Two: Symbol('two'),
  Three: Symbol('three')
});
```

### JSON Serialization

```typescript
const Color = Enum({
  Red: 'RED',
  Green: 'GREEN',
  Blue: 'BLUE'
});

// Serialize
const json = JSON.stringify(Color);
// '{"Red":"RED","Green":"GREEN","Blue":"BLUE"}'

// Deserialize
const deserialized = Enum(JSON.parse(json));
```

## About Enum Labels

This library intentionally does not provide strictly typed literal types for enum labels. While it would be technically possible (and relatively straightforward) to implement this feature, it's a deliberate design choice based on the following principles:

1. **Separation of Concerns**: Enum labels should be used purely for display purposes and debugging. They should not be used for making programmatic decisions in your code.

2. **Maintainability**: If you need to change a label for display purposes, you shouldn't have to update type definitions throughout your codebase.

3. **Best Practices**: Using enum labels for programmatic decisions can lead to brittle code that's hard to maintain. Instead, you should:
   - Use enum values for programmatic decisions
   - Use labels only for display, logging, or debugging purposes
   - If you need to make decisions based on enum members, use the values directly

Example of what NOT to do:
```typescript
// ❌ Don't do this
if (Enum.reversed(Color).get(value) === 'Red') {
  // Making decisions based on labels
}

// ✅ Do this instead
if (value === Color.Red) {
  // Making decisions based on values
}
```

## License

MIT