@practical-fp/union-types
v1.5.1
Published
A Typescript library for creating discriminating union types.
Downloads
11,355
Maintainers
Readme
Union Types
A Typescript library for creating discriminating union types. Requires Typescript 4.2 or higher.
Typescript Handbook on discriminating union types
Example
import { impl, Variant, match } from "@practical-fp/union-types"
type Shape =
| Variant<"Circle", { radius: number }>
| Variant<"Square", { sideLength: number }>
const { Circle, Square } = impl<Shape>()
function getArea(shape: Shape) {
return match(shape)
.with(Circle, ({ radius }) => Math.PI * radius ** 2)
.with(Square, ({ sideLength }) => sideLength ** 2)
.done()
}
const circle = Circle({ radius: 5 })
const area = getArea(circle)Installation
$ npm install @practical-fp/union-typesUsage
Defining a discriminating union type
import { Variant } from "@practical-fp/union-types"
type Shape =
| Variant<"Circle", { radius: number }>
| Variant<"Square", { sideLength: number }>This is equivalent to the following type:
type Shape =
| { type: "Circle", value: { radius: number } }
| { type: "Square", value: { sideLength: number } }Creating an implementation
import { impl } from "@practical-fp/union-types"
const { Circle, Square } = impl<Shape>()impl<>() can only be used if your environment has full support
for Proxies.
Circle.is and Square.is can be used to check if a shape is a circle or a square.
They also act as type guards.
const shapes: Shape[] = [circle, square]
const sideLengths = shapes.filter(Square.is).map(square => square.value.sideLength)Generics
impl<>() also supports generic union types.
In case the variant type uses unconstrained generics,
unknown needs to be passed as its type arguments.
import { impl, Variant } from "@practical-fp/union-types"
type Result<T, E> =
| Variant<"Ok", T>
| Variant<"Err", E>
const { Ok, Err } = impl<Result<unknown, unknown>>()In case the variant type uses constrained generics, the constraint type needs to be passed as its type arguments.
import { impl, Variant } from "@practical-fp/union-types"
type Result<T extends object, E> =
| Variant<"Ok", T>
| Variant<"Err", E>
const { Ok, Err } = impl<Result<object, unknown>>()