What if you could write something like:
const value = if (condition) {
optionA;
} else {
optionB;
};
Enter, cont-flow-expr.if
:
import fi from "cont-flow-expr.if";
const value = fi(condition)
.then(optionA)
.else(optionB);
A basic if-else
expression can be written as:
import fi from "cont-flow-expr.if";
const value = fi(condition)
.then(optionA)
.else(optionB);
Branches can also be evaluated lazily:
import fi from "cont-flow-expr.if";
const value = fi(condition)
.thenDo(() => optionA)
.elseDo(() => optionB);
Normal and lazy branches can be mixed arbitrarily, for example:
import fi from "cont-flow-expr.if";
const value = fi(condition)
.thenDo(() => expensiveOption)
.else(cheapOption);
An if-elseif-else
expression can be written as:
import fi from "cont-flow-expr.if";
const value = fi(condition1)
.then(optionA)
.elseIf(condition2)
.then(optionB)
// .elseIf(conditionN-1)
// .then(optionN-1)
.else(optionZ);
with arbitrarily many uses of .elseIf().then()
.
Here too branches can be evaluated lazily and mixed with normal branches arbitrarily:
import fi from "cont-flow-expr.if";
const value = fi(condition1)
.then(optionA)
.elseIf(condition2)
.thenDo(() => optionB)
.else(optionC);
Else conditions can be evaluated lazily by using .elseIfLazy()
, for example:
import fi from "cont-flow-expr.if";
const value = fi(condition1)
.then(optionA)
.elseIfLazy(() => condition2) // not run if `condition1` holds
.thenDo(() => optionB)
.else(optionC);
TypeScript support is included and can be used to ensure all branches evaluate to the same type (union). Type parameters are required for this to work. For example:
import fi from "cont-flow-expr.if";
const condition = true, optionA = "foo", optionB = "bar", optionC = 42;
// Works
const aString = fi<string>(condition)
.then(optionA)
.else(optionB);
// Fails
const fails = fi<string>(condition)
.then(optionA)
.else(optionC);
// ~~~~~~~> TypeError:
// Argument of type 'number' is not assignable to parameter of type 'string'.
// Works
const aStringOrNumber = fi<string | number>(condition)
.then(optionA)
.else(optionC);
The benchmarks in this project - which are powered by Benchmark.js - can be used to compare this library against vanilla JavaScript as well as alternative libraries. Here's a sample result:
vanilla x 1,409,198,725 ops/sec ±0.16% (97 runs sampled)
cont-flow-expr x 68,040,893 ops/sec ±0.53% (96 runs sampled)
dolla-if x 60,359,107 ops/sec ±0.36% (99 runs sampled)
-
cont-flow-expr.switch
- Switch statements as expressions. -
cont-flow-expr.try
- Try statements as expressions. -
cont-flow-expr
- Combines this and all of the above into one convenient package.
The source code is licensed under the ISC license. The documentation text is licensed under CC BY 4.0.