### Install Unionize with Yarn Source: https://github.com/pelotom/unionize/blob/master/README.md Installs the unionize package using the Yarn package manager. This is the first step to using unionize in your project. ```bash yarn add unionize ``` -------------------------------- ### Unionize Match Expression for Reducers Source: https://github.com/pelotom/unionize/blob/master/README.md Shows how to use the `match` expression provided by `unionize` to handle different cases of a tagged union, similar to a switch statement but with type safety. This is particularly useful in reducers. ```typescript const todosReducer = (state: Todo[] = [], action: Action) => Actions.match(action, { ADD_TODO: ({ id, text }) => [...state, { id, text, completed: false }], TOGGLE_TODO: ({ id }) => state.map(todo => todo.id === id ? { ...todo, completed: !todo.completed } : todo ), default: a => state }); // Curried version example: const getIdFromAction = Actions.match({ ADD_TODO: ({ id}) => id, TOGGLE_TODO: ({ id }) => id, default: a => { throw new Error(`Action type ${a.type} does not have an associated id`); }, }); const action = Actions.ADD_TODO({ id: 'c819bbc1', text: 'Take out the trash' }); const id = getIdFromAction(action); // id === 'c819bbc1' ``` -------------------------------- ### Define a Basic Tagged Union with Unionize Source: https://github.com/pelotom/unionize/blob/master/README.md Demonstrates how to define a tagged union using the `unionize` and `ofType` functions. It maps string tags to their corresponding value types, including empty types. ```typescript import { unionize, ofType } from 'unionize'; const Actions = unionize({ ADD_TODO: ofType<{ id: string; text: string }>(), CLEAR_TODOS: {}, // For "empty" types, just use {} }); ``` -------------------------------- ### Unionize Element Factory Usage Source: https://github.com/pelotom/unionize/blob/master/README.md Demonstrates how to use the element factories generated by `unionize` to create union members. These factories simplify dispatching actions or creating union instances. ```typescript store.dispatch(Actions.ADD_TODO({ id: 'c819bbc1', text: 'Take out the trash' })); store.dispatch(Actions.SET_VISIBILITY_FILTER('SHOW_COMPLETED')); store.dispatch(Actions.CLEAR_TODOS()); // no argument required if value type is {} ``` -------------------------------- ### Unionize Match Function Updates (1.0.1) Source: https://github.com/pelotom/unionize/blob/master/README.md Explains the modifications to the `match` function in Unionize. It can now accept the object to match as the first argument, and the default case is handled as a property within the cases object. ```typescript // before Light.match({ On: () => 'is on' }, () => 'is off' )(light); // after Light.match({ On: () => 'is on', default: () =>'is off' })(light); Light.match(light, { On: () => 'is on', default: () => 'is off', }); ``` -------------------------------- ### Extending Unions with Spread in Unionize Source: https://context7.com/pelotom/unionize/llms.txt Illustrates how to extend an existing Unionize union by spreading its `_Record` property into a new union definition. This allows for composing unions and creating more complex type structures. ```typescript import { unionize, ofType, UnionOf } from 'unionize'; // Base union const HttpMethod = unionize({ GET: ofType<{ url: string }>(), POST: ofType<{ url: string; body: unknown }>(), }, { tag: 'method', value: 'config' }); // Extended union with additional variants const FullHttpMethod = unionize({ PUT: ofType<{ url: string; body: unknown }>(), DELETE: ofType<{ url: string }>(), PATCH: ofType<{ url: string; body: unknown }>(), ...HttpMethod._Record, // Spread base union's record }, { tag: 'method', value: 'config' }); type Method = UnionOf; // All variants are available const get = FullHttpMethod.GET({ url: '/api/users' }); const post = FullHttpMethod.POST({ url: '/api/users', body: { name: 'John' } }); const put = FullHttpMethod.PUT({ url: '/api/users/1', body: { name: 'Jane' } }); const del = FullHttpMethod.DELETE({ url: '/api/users/1' }); console.log(get); // { method: 'GET', config: { url: '/api/users' } } console.log(post); // { method: 'POST', config: { url: '/api/users', body: { name: 'John' } } } // Match works across all variants const describe = FullHttpMethod.match({ GET: ({ url }) => `GET ${url}`, POST: ({ url }) => `POST ${url}`, PUT: ({ url }) => `PUT ${url}`, DELETE: ({ url }) => `DELETE ${url}`, PATCH: ({ url }) => `PATCH ${url}`, }); console.log(describe(get)); // 'GET /api/users' ``` -------------------------------- ### Unionize Config Object Breaking Changes (1.0.1) Source: https://github.com/pelotom/unionize/blob/master/README.md Illustrates the change in how the `unionize` function accepts configuration. Previously, it took separate arguments for tag and payload property names; now, it uses a single config object. ```typescript // before unionize({...}, 'myTag', 'myPayloadProp'); unionize({...}, 'myTag'); // after unionize({...}, { tag:'myTag', value:'myPayloadProp' }); unionize({...}, { tag:'myTag' }); unionize({...}, { value:'myPayloadProp' }); // <-- previously not possible ``` -------------------------------- ### Unionize Type Guard Usage Source: https://github.com/pelotom/unionize/blob/master/README.md Demonstrates how to use type guards generated by `unionize` to narrow down the type of a union member within conditional blocks. This enhances type safety when working with observables or other streams. ```typescript const epic = (action$: Observable) => action$ .filter(Actions.is.ADD_TODO) .mergeMap(({ payload }) => console.log(payload.text)); ``` -------------------------------- ### Transform Union Expressions in TypeScript Source: https://github.com/pelotom/unionize/blob/master/README.md Demonstrates how to use the `transform` function in Unionize to conditionally convert between union types. It handles subsets of cases, leaving others unchanged, and can accept an object directly for transformation. ```typescript const Light = unionize({ On: ofType<{ percentage: number }>(), Off: {} }); const turnOn = Light.transform({ Off: () => Light.On({ percentage: 100 }) }); const dim = Light.transform({ On: prev => Light.On({ percentage: prev.percentage / 2 }) }); const off = Light.Off(); const dimmed = dim(off); //didn't match. so dimmed === off const on = turnOn(off); // can accept an object right away const toggled = Light.transform(on, { On: () => Light.Off(), Off: () => Light.On({ percentage: 50 }), }); ``` -------------------------------- ### Infer Tagged Union Type with UnionOf Source: https://github.com/pelotom/unionize/blob/master/README.md Shows how to extract the TypeScript type definition of a tagged union created with `unionize`. The `UnionOf` helper infers the structure of the union based on the defined tags and value types. ```typescript import { UnionOf } from 'unionize' type Action = UnionOf; ``` -------------------------------- ### Partial Transformation with Unionize Source: https://context7.com/pelotom/unionize/llms.txt Demonstrates how to use the `transform` function in Unionize to selectively update union variants. This is useful for state machines and incremental updates where only specific cases need to be handled, leaving others unchanged. ```typescript import { unionize, ofType } from 'unionize'; const Light = unionize({ Off: {}, On: ofType<{ brightness: number }>(), Dimmed: ofType<{ brightness: number }>(), }); // Create transformation functions const turnOn = Light.transform({ Off: () => Light.On({ brightness: 100 }), }); const turnOff = Light.transform({ On: () => Light.Off(), Dimmed: () => Light.Off(), }); const dim = Light.transform({ On: ({ brightness }) => Light.Dimmed({ brightness: brightness / 2 }), }); const brighten = Light.transform({ Dimmed: ({ brightness }) => Light.On({ brightness: Math.min(100, brightness * 2) }), }); // Chain transformations let light = Light.Off(); console.log(light); // { tag: 'Off' } light = turnOn(light); console.log(light); // { tag: 'On', brightness: 100 } light = dim(light); console.log(light); // { tag: 'Dimmed', brightness: 50 } light = brighten(light); console.log(light); // { tag: 'On', brightness: 100 } light = turnOff(light); console.log(light); // { tag: 'Off' } // Unmatched cases return the original value unchanged const alreadyOff = Light.Off(); const stillOff = turnOff(alreadyOff); console.log(stillOff === alreadyOff); // true (same reference) // Inline transform with variant as first argument const toggled = Light.transform(Light.On({ brightness: 75 }), { On: () => Light.Off(), Off: () => Light.On({ brightness: 100 }), }); console.log(toggled); // { tag: 'Off' } ``` -------------------------------- ### Unionize Type Cast Usage Source: https://github.com/pelotom/unionize/blob/master/README.md Illustrates how to use type casts provided by `unionize` to assert the type of a union member. This is useful when you are certain about the type and want to access its specific properties, but it will throw an error if the assertion is incorrect. ```typescript const { id, text } = Actions.as.ADD_TODO(someAction); // throws if someAction is not an ADD_TODO ``` -------------------------------- ### Define Tagged Union with Custom Tag and Value Properties Source: https://github.com/pelotom/unionize/blob/master/README.md Illustrates defining a tagged union with custom property names for the tag and value. This allows for integration with standards like Flux Standard Actions (FSA) by specifying 'type' and 'payload' properties. ```typescript import { unionize, ofType } from 'unionize' const Actions = unionize({ ADD_TODO: ofType<{ id: string; text: string }>(), SET_VISIBILITY_FILTER: ofType<'SHOW_ALL' | 'SHOW_ACTIVE' | 'SHOW_COMPLETED'>(), TOGGLE_TODO: ofType<{ id: string }>(), CLEAR_TODOS: {}, }, { tag:'type', value:'payload', }); type Action = UnionOf; ``` -------------------------------- ### Pattern Matching with Unionize 'match' in TypeScript Source: https://context7.com/pelotom/unionize/llms.txt Performs exhaustive pattern matching on union variants using the 'match' function. It can be called with cases only (returning a function) or with a variant and cases (returning the result directly). Supports a 'default' case for partial matching. ```typescript import { unionize, ofType } from 'unionize'; const Shape = unionize({ Circle: ofType<{ radius: number }>(), Rectangle: ofType<{ width: number; height: number }>(), Triangle: ofType<{ base: number; height: number }>(), }); // Exhaustive matching - all cases required const calculateArea = Shape.match({ Circle: ({ radius }) => Math.PI * radius * radius, Rectangle: ({ width, height }) => width * height, Triangle: ({ base, height }) => (base * height) / 2, }); const circle = Shape.Circle({ radius: 5 }); console.log(calculateArea(circle)); // 78.54... // Inline matching - pass variant as first argument const rect = Shape.Rectangle({ width: 10, height: 20 }); const area = Shape.match(rect, { Circle: ({ radius }) => Math.PI * radius * radius, Rectangle: ({ width, height }) => width * height, Triangle: ({ base, height }) => (base * height) / 2, }); console.log(area); // 200 // Partial matching with default case const isCircle = Shape.match({ Circle: () => true, default: () => false, }); console.log(isCircle(circle)); // true console.log(isCircle(rect)); // false // Default receives the original variant const describe = Shape.match({ Circle: ({ radius }) => `Circle with radius ${radius}`, default: (shape) => `Non-circle shape with tag: ${shape.tag}`, }); ``` -------------------------------- ### Define Type Witness with ofType (TypeScript) Source: https://context7.com/pelotom/unionize/llms.txt The `ofType` helper creates a type witness for a given type within the `unionize` record. It returns `undefined` at runtime but provides the necessary type information for TypeScript inference, allowing for correct payload typing of union variants. ```typescript import { unionize, ofType } from 'unionize'; // ofType() creates a type witness for T const Result = unionize({ Success: ofType<{ data: string[] }>(), Error: ofType<{ message: string; code: number }>(), Loading: {}, }); // The type witness allows TypeScript to infer the correct payload types const success = Result.Success({ data: ['item1', 'item2'] }); const error = Result.Error({ message: 'Not found', code: 404 }); const loading = Result.Loading(); ``` -------------------------------- ### Create Tagged Union with unionize (TypeScript) Source: https://context7.com/pelotom/unionize/llms.txt The `unionize` function creates a tagged union from a record mapping tags to value types. It returns an object with variant constructors, type predicates, casts, and matching functions. It supports basic usage with merged value types and custom tag/value property names for FSA-compliant actions. ```typescript import { unionize, ofType } from 'unionize'; // Basic usage - merged value types (values spread into the tagged object) const Actions = unionize({ ADD_TODO: ofType<{ id: string; text: string }>(), TOGGLE_TODO: ofType<{ id: string }>(), CLEAR_TODOS: {}, }); // Create variants const addAction = Actions.ADD_TODO({ id: '1', text: 'Buy milk' }); // Result: { tag: 'ADD_TODO', id: '1', text: 'Buy milk' } const clearAction = Actions.CLEAR_TODOS(); // Result: { tag: 'CLEAR_TODOS' } // With custom tag and value property names (FSA-compliant) const FSAActions = unionize({ ADD_TODO: ofType<{ id: string; text: string }>(), SET_FILTER: ofType<'SHOW_ALL' | 'SHOW_ACTIVE' | 'SHOW_COMPLETED'>(), }, { tag: 'type', value: 'payload' }); const fsaAction = FSAActions.ADD_TODO({ id: '1', text: 'Buy milk' }); // Result: { type: 'ADD_TODO', payload: { id: '1', text: 'Buy milk' } } const filterAction = FSAActions.SET_FILTER('SHOW_COMPLETED'); // Result: { type: 'SET_FILTER', payload: 'SHOW_COMPLETED' } ``` -------------------------------- ### Type Casts with Unionize 'as' in TypeScript Source: https://context7.com/pelotom/unionize/llms.txt Offers cast functions for each union variant, extracting the value if the variant matches. Throws an error if the cast fails, useful when the variant type is certain. ```typescript import { unionize, ofType, UnionOf } from 'unionize'; const Response = unionize({ Data: ofType<{ items: string[]; total: number }>(), Error: ofType<{ code: number; message: string }>(), }, { tag: 'type', value: 'payload' }); const success = Response.Data({ items: ['a', 'b'], total: 2 }); const failure = Response.Error({ code: 500, message: 'Server error' }); // Safe cast when you know the type const data = Response.as.Data(success); console.log(data.items); // ['a', 'b'] console.log(data.total); // 2 // Throws error if cast fails try { const wrongCast = Response.as.Data(failure); } catch (e) { console.log(e.message); // 'Attempted to cast Error as Data' } // Use with confidence after type guard function getItems(response: UnionOf): string[] { if (Response.is.Data(response)) { return Response.as.Data(response).items; } return []; } ``` -------------------------------- ### Type Guards with Unionize 'is' in TypeScript Source: https://context7.com/pelotom/unionize/llms.txt Provides type guard functions for each union variant, enabling proper TypeScript type narrowing. Returns true if the variant matches the specified tag. ```typescript import { unionize, ofType, UnionOf } from 'unionize'; const Result = unionize({ Success: ofType<{ data: string }>(), Error: ofType<{ message: string }>(), Pending: {}, }); type ResultType = UnionOf; function processResult(result: ResultType): string { // Type guard narrows the type if (Result.is.Success(result)) { // TypeScript knows result is { tag: 'Success'; data: string } return `Got data: ${result.data}`; } if (Result.is.Error(result)) { // TypeScript knows result is { tag: 'Error'; message: string } return `Error: ${result.message}`; } // TypeScript knows result is { tag: 'Pending' } return 'Still loading...'; } // Useful with array filtering const results: ResultType[] = [ Result.Success({ data: 'item1' }), Result.Error({ message: 'failed' }), Result.Success({ data: 'item2' }), Result.Pending(), ]; const successResults = results.filter(Result.is.Success); // Type: Array<{ tag: 'Success'; data: string }> console.log(successResults.map(r => r.data)); // ['item1', 'item2'] // Works great with RxJS/Observable filtering // action$.pipe(filter(Actions.is.ADD_TODO)).subscribe(action => { // console.log(action.id, action.text); // Properly typed // }); ``` -------------------------------- ### Extract Union Type with UnionOf (TypeScript) Source: https://context7.com/pelotom/unionize/llms.txt The `UnionOf` type utility extracts the inferred tagged union type from a unionized record created by `unionize`. This is crucial for correctly typing function parameters and variables that will hold instances of the union type, ensuring type safety. ```typescript import { unionize, ofType, UnionOf } from 'unionize'; const Actions = unionize({ Increment: ofType<{ amount: number }>(), Decrement: ofType<{ amount: number }>(), Reset: {}, }); // Extract the union type for use in function signatures type Action = UnionOf; function reducer(state: number, action: Action): number { return Actions.match(action, { Increment: ({ amount }) => state + amount, Decrement: ({ amount }) => state - amount, Reset: () => 0, }); } const result = reducer(10, Actions.Increment({ amount: 5 })); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.