ts-xor
    TypeScript icon, indicating that this package has built-in type declarations

    1.0.8 • Public • Published

    ts-xor

    Compose custom types containing mutually exclusive keys, using this generic Typescript helper type.

    npm version Build Status Greenkeeper badge Last commit

    Licence Downloads per week NPM dependent packages Github stars

    Minified and gzipped size Dependencies

    Description

    Typescript's union operator (|) allows combining two types A and B, into a superset type C which can contain all the members of both A and B.

    But sometimes the requirements dictate that we combine two types with mutually exclusive members. So take the members A.a and B.b. Given type C = A | B then we want to impose the restriction that we can set either C.a or C.b but never both AND at least one of the two!

    Typescript does not support this feature out of the box yet.

    This package introduces the new type XOR. You can use XOR to compose your own custom types with mutually exclusive members.

    XOR effectively implements the logical XOR operator from boolean algebra as defined by the following truth table:

    A B Result
    0 0 0
    0 1 1
    1 0 1
    1 1 0

    Installation

    In your typescript powered, npm project, run:

    npm install -D ts-xor # yarn add -D ts-xor 

    Examples

    A simple example

    In any typescript file you can just have:

    import { XOR } from 'ts-xor'
     
    interface A {
      a: string
    }
     
    interface B {
      b: string
    }
     
    let A_XOR_B: XOR<A, B>
     
    A_XOR_B = { a: '' }         // OK
    A_XOR_B = { b: '' }         // OK
    A_XOR_B = { a: '', b: '' }  // fails
    A_XOR_B = {}                // fails

    A real-life example

    Say that we have the following specification for the response of a weather forecast service:

    1. A weather forecast object always contains the id and station members
    2. A weather forecast object always contains either a member rain or a member snow, but never both at the same time.
    3. The rain or snow members are objects containing additional forecast accuracy data
    4. The rain or snow member always contain either a member 1h or a member 3h with a number value, but never both keys at the same time.
    import { XOR } from 'ts-xor'
     
    type ForecastAccuracy = XOR<{ '1h': number }, { '3h': number }>
     
    interface WeatherForecastBase {
      id: number
      station: string
    }
     
    interface WeatherForecastWithRain extends WeatherForecastBase {
      rain: ForecastAccuracy
    }
     
    interface WeatherForecastWithSnow extends WeatherForecastBase {
      snow: ForecastAccuracy
    }
     
    type WeatherForecast = XOR<WeatherForecastWithRain, WeatherForecastWithSnow>
     
    const ourTestCase: WeatherForecast = {
      id: 123456,
      station: 'Acropolis Weather Reporter',
      // rain: { '1h': 1 },           // OK
      // rain: { '2h': 1 },           // fails
      // rain: { '3h': 1 },           // OK
      // rain: {},                    // fails
      // rain: { '1h': 1 , '3h': 3 }, // fails
      // lel: { '3h': 1 },            // fails
      // snow: { '3h': 1 },           // OK
      // when BOTH `rain` AND `snow` are declared, compilation fails
    }

    Tests and Coverage

    The library ts-xor is fully covered with acceptance and mutation tests against the typescript compiler itself. The tests can be found inside the test folder.

    To run all tests locally, execute the following command inside your git-cloned ts-xor folder:

    npm test

    NPM

    This library is published on NPM.

    Licence

    Distributed under the MIT license. See LICENSE.md for more information.

    Contributing

    This project's commits comply with the Conventional Commits guidelines.

    1. Fork it (https://github.com/maninak/ts-xor/fork)
    2. Create your feature/fix branch (git checkout -b feat/foobar)
    3. Commit your changes (git commit -am 'feat(foobar): add support for foobar tricks')
    4. Push to the branch (git push origin feat/fooBar)
    5. Create a new Pull Request

    Install

    npm i ts-xor

    DownloadsWeekly Downloads

    29,091

    Version

    1.0.8

    License

    MIT

    Unpacked Size

    8.91 kB

    Total Files

    15

    Last publish

    Collaborators

    • maninak