@antivixen/andor
TypeScript icon, indicating that this package has built-in type declarations

0.1.7 • Public • Published

andor

Small (<1kb) library for utilizing type safe and predictable methods to deal with conditional statements.

Contents

Installation

  • Using npm - npm install @antivixen/andor
  • Using yarn - yarn add @antivixen/andor
  • Using pnpm - pnpm add @antivixen/andor

Methods

  • getEvaluation<T>:
const result = getEvaluation({
  case: true,
  and: () => "True",
  or: () => "False",
});

console.log(result);
// result === "True"

Generic type is optional, however you might need to specify in case the return type is a union type, otherwise you'll gent an error:

const result = getEvaluation<string | null>({
  case: false,
  and: () => "True",
  or: {
    case: true,
    and: () => "False",
    or: () => null,
  },
});

console.log(result);
// result === "False"

and / or method in the scheme might be either a function or another scheme object:

type Scheme = {
  case: boolean // any other types passing through will be converted to boolean
  and() {
    // either function or Scheme
  }
  or(){
    //either function or Scheme
  }
}
  • getCase<T, I>: Functional alternative to JS Switch Statement
type Case = "True" | "False";
const value: Case = getValueFromSomewhere();

const result = getCase({
  switch: value,
  default: "It's unknown",
  cases: { True: "It's true", False: "It's false" },
});

Generics are optional, if you'd like to be more specific go ahead with `getCase<Options, Result>':

const result = getCase<"True" | "False", "It's true" | "It's false">({
  switch: value,
  default: "It's unknown",
  cases: { True: "It's true", False: "It's false" },
});

See some advanced use cases in Examples

Examples

Here are some particular cases for using the methods

  • getEvaluation:
type Status = "Guest" | "User" | "Editor" | "Admin";

let isUserAuthorised;
let isAdmin;
let isEditor;

If you need to get the user status, based on the provided variables you have the following options:

const userStatus: Status = isUserAuthorised
  ? isAdmin
    ? "Admin"
    : isEditor
    ? "Editor"
    : "User"
  : "Guest";

Not a great idea given it's not just super hard to follow the flow, but also should be forbidden in eslint

let userStatus: Status;
if (isUserAuthorised) {
  if (isAdmin) {
    userStatus = "Admin";
  } else if (isEditor) {
    userStatus = "Editor";
  } else {
    userStatus = "User";
  }
} else {
  userStatus = "Guest";
}

This case clearly needs a separate method, which is + 1 level of abstraction, additionally not a great choice flow / immutability wise

const userStatus = ((): Status => {
  if (isUserAuthorised) {
    if (isAdmin) {
      return "Admin";
    }
    if (isEditor) {
      return "Editor";
    }
    return "User";
  }
  return "Guest";
})();

You might recall the good old IIFE and come up with a much better construction. However, it can be a bit inconvenient to read in certain edge cases

const userStatus = getEvaluation<Status>({
  case: isUserAuthorised,
  or: () => "Guest",
  and: {
    case: isAdmin,
    and: () => "Admin",
    or: {
      case: isEditor,
      and: () => "Editor",
      or: () => "User",
    },
  },
});

The getEvaluation method provides a clear scheme of all possible cases, and the returning functions can have side effects, such as acting as a middleware if necessary.

  • getCase: Yet to be written..

Package Sidebar

Install

npm i @antivixen/andor

Weekly Downloads

3

Version

0.1.7

License

MIT

Unpacked Size

24.4 kB

Total Files

17

Last publish

Collaborators

  • antivixen