https://github.com/kube/when-switch
JavaScript functional implementation of switch/case
https://github.com/kube/when-switch
functional javascript pattern-matching switch typescript
Last synced: 9 months ago
JSON representation
JavaScript functional implementation of switch/case
- Host: GitHub
- URL: https://github.com/kube/when-switch
- Owner: kube
- License: mit
- Created: 2016-10-07T12:19:20.000Z (over 9 years ago)
- Default Branch: master
- Last Pushed: 2022-12-07T09:16:44.000Z (over 3 years ago)
- Last Synced: 2025-10-05T02:25:21.061Z (9 months ago)
- Topics: functional, javascript, pattern-matching, switch, typescript
- Language: TypeScript
- Homepage:
- Size: 347 KB
- Stars: 22
- Watchers: 2
- Forks: 0
- Open Issues: 16
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
[](https://circleci.com/gh/kube/when-switch)
when-switch
JavaScript functional implementation of switch/case, inspired by Ruby case/when.
## Usage
You can convert a switch-case use in a functional way, using a single expression:
### Strict Equality
```js
import when from 'when-switch'
const getDrinkPrice = drink =>
when(drink)
.is('Coke', 1.5)
.is('Pepsi', 1.8)
.else(2.0)
```
### Structural Matching
You can use `match` method with any object exposing a `test` method.
#### Regular Expressions
```js
const getCaseStyle = text =>
when(text)
.match(/^([A-Z][a-z]*)+$/, 'UpperCamelCase')
.match(/^([a-z]+[A-Z][a-z]*)+$/, 'LowerCamelCase')
.match(/^([a-z]+_[a-z]+)+$/, 'SnakeCase')
.else('Unknown')
```
#### Custom Type Guard Matcher
```ts
type SpaceObject = { x: number; y: number; z: number }
type Cube = SpaceObject & { width: number }
type Sphere = SpaceObject & { radius: number }
const SpaceObjectSchema = {
test: (_: any): _ is SpaceObject =>
typeof _.x === 'number' &&
typeof _.y === 'number' &&
typeof _.z === 'number'
}
const CubeSchema = {
test: (_: any): _ is Cube =>
typeof _.width === 'number' && SpaceObjectSchema.test(_)
}
const SphereSchema = {
test: (_: any): _ is Sphere =>
typeof _.radius === 'number' && SpaceObjectSchema.test(_)
}
const getObjectVolume = (object: SpaceObject) =>
// Each match handler will receive correct static type
when(object)
.match(CubeSchema, cube => cube.width ** 3)
.match(SphereSchema, sphere => Math.PI * 3 / 4 * sphere.radius ** 3)
.else(_ => null)
```
> `match` and `is` can both be used in the same `when` expression.
## TypeScript
`when` is fully compatible with TypeScript, and will check the types you return in each `is` expression:
```js
const getDrinkPrice = (drink: 'Pepsi' | 'Coke' | 'Orangina'): number =>
when(drink)
.is('Coke', 1.5)
.is('Pepsi', 1.8)
.else(2.0)
```
Here the return type of the `when` expression will be `number`
### Union types
For each `is` or `else` expression added to the current `when` expression, the type is added as an union to the previous type.
```js
const getDrinkPrice = (drink: 'Pepsi' | 'Coke' | 'Orangina') =>
when(drink)
.is('Coke', 1.5)
.is('Pepsi', true)
.else('Free')
```
Here the return type of `getDrinkPrice` expression will be `number | string | boolean`