0.0.10 • Public • Published


    Tagged unions

    npm install tagmeme

    npm Build Status Greenkeeper badge

    Tagmeme is a library for building tagged unions. This project offers:

    • A concise API for pattern matching and variant constructors
    • Data-oriented tags that can be serialized and namespaced
    • Errors in development to ensure exhaustive pattern matching
    • Small size and zero-dependencies in production using dead code elimination

    Let's check it out.


    import assert from 'assert'
    import { union } from 'tagmeme'
    const Result = union(['Ok', 'Err'])
    const err = Result.Err(new Error('My error'))
    const message = Result.match(err, {
      Ok: () => 'No error',
      Err: error => error.message
    assert(message === 'My error')
    const handle = Result.matcher({
      Ok: () => 'No error',
      Err: error => error.message
    assert(handle(err) === 'My error')
    const isError = Result.matches(err, Result.Err)


    This package includes:


    union(types: Array<String>[, options: { prefix: String }]): Union

    Create a tagged union. Throws if:

    • types is not an array of unique strings
    • any types are named "match", "matcher", or "matches"

    See safeUnion if using arbitrary strings.


    Union[type](data: any): ({ type, data })

    Create a tag of the union containing data which can be retrieved via Union.match.

    import assert from 'assert'
    import { union } from 'tagmeme'
    const Result = union(['Ok', 'Err'])
    const result = Result.Ok('good stuff')
    assert(result.type === 'Ok')
    assert(result.data === 'good stuff')


    Union.match(tag, handlers[, catchAll: function])

    Pattern match on tag with a hashmap of handlers where keys are kinds and values are functions, with an optional catchAll if no handler matches the value. Throws if:

    • tag is not of any of the union types
    • tag does not match any type and there is no catchAll
    • any handlers key is not a kind in the union
    • any handlers value is not a function
    • it handles all cases and there is a useless catchAll
    • it does not handle all cases and there is no catchAll
    import assert from 'assert'
    import { union } from 'tagmeme'
    const Result = union(['Ok', 'Err'])
    const result = Result.Err('Request failed')
    const status = Result.match(
      { Err: () => 400 },
      () => 200
    assert(status === 400)


    Union.matcher(handlers[, catchAll: function])

    Create a matching function which will take tag and context arguments. This reduces the boilerplate of a function that delegates to Union.match with static handlers. This is also a bit faster than match because the handler functions only need to be created once.

    Unlike with match, the second argument to handlers will be context to avoid the need for a closure.

    import assert from 'assert'
    import { union } from 'tagmeme'
    const Result = union(['Ok', 'Err'])
    const collectErrors = Result.matcher({
      Ok: (_, errors) => errors,
      Err: (error, errors) => errors.concat(error)
    const errors = collectErrors(Result.Err('Bad'), [])
    assert.deepEqual(errors, ['Bad'])


    Union.matches(tag, variant: Variant): Boolean

    Determine whether a given tag is of variant.

    import assert from 'assert'
    import { union } from 'tagmeme'
    const Result = union(['Ok', 'Err'])
    const okTag = Result.Ok(1)
    assert(Result.matches(okTag, Result.Ok))


    safeUnion(types: Array<String>[, options: { prefix: String }]): { methods, variants }

    For library authors accepting arbitrary strings for type names, safeUnion is union but returns distinct collections of methods and type variants. This will not throw if a type is "match", "matcher", or "matches".


    tagmeme |ˈtaɡmiːm|: a slot in a syntactic frame which may be filled by any member of a set of appropriate linguistic items.

    This name is kind of fitting for a tagged union library.


    npm i tagmeme

    DownloadsWeekly Downloads






    Unpacked Size

    22.5 kB

    Total Files


    Last publish


    • andrejewski