@pedromsilva/data-either
Version:
Simple TypeScript/ES2017 class to represent either values
270 lines • 8.4 kB
JavaScript
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var WrongSideError = /** @class */ (function (_super) {
__extends(WrongSideError, _super);
function WrongSideError() {
return _super !== null && _super.apply(this, arguments) || this;
}
return WrongSideError;
}(Error));
exports.WrongSideError = WrongSideError;
var EitherSide;
(function (EitherSide) {
EitherSide[EitherSide["Left"] = 0] = "Left";
EitherSide[EitherSide["Right"] = 1] = "Right";
})(EitherSide = exports.EitherSide || (exports.EitherSide = {}));
var Either = /** @class */ (function () {
function Either(side, value) {
this.side = side;
this.value = value;
}
Object.defineProperty(Either.prototype, "left", {
get: function () {
return this.value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Either.prototype, "right", {
get: function () {
return this.value;
},
enumerable: true,
configurable: true
});
/**
* Instantiates an Either object with a left value.
*
* @static
* @template L
* @template R
* @param {L} value
* @returns {Either<L, R>}
* @memberof Either
*/
Either.left = function (value) {
return new Either(EitherSide.Left, value);
};
/**
* Instantiates an Either object, with a right value.
*
* @static
* @template L
* @template R
* @param {R} value
* @returns {Either<L, R>}
* @memberof Either
*/
Either.right = function (value) {
return new Either(EitherSide.Right, value);
};
/**
* Converts a function that might throw an error into an Either object.
* Left represents the successful return value of the function.
* Right represents the catched value in the try ... catch.
*
* @static
* @template L
* @template R
* @param {Supplier<L>} supplier
* @returns {Either<L, R>}
* @memberof Either
*/
Either.ofThrowable = function (supplier) {
try {
return Either.left(supplier());
}
catch (error) {
return Either.right(error);
}
};
/**
* Converts a NodeJS-style async callback that receives an error and a value.
* If the error is different than null, calls the callback with the error on the right
* side. If error is null, calls the callback with the value on the left side.
*
* @static
* @template L
* @template R
* @param {Consumer<Either<L, R>>} cb
* @returns {( err : R, value : L ) => void}
* @memberof Either
*/
Either.ofCallback = function (cb) {
return function (err, value) {
if (err) {
cb(Either.right(err));
}
cb(Either.left(value));
};
};
/**
* Converts a promise of a value that might return a rejection into a
* promise that always resolves with an Either object.
*
* Left represents the resolve of the original promise,
* while Right represents a rejection.
*
* @static
* @template L
* @template R
* @param {Promise<L>} promise
* @returns {Promise<Either<L, R>>}
* @memberof Either
*/
Either.ofPromise = function (promise) {
return promise
.then(function (value) { return Either.left(value); })
.catch(function (error) { return Either.right(error); });
};
/**
* Returns a boolean indicating if this object represents a left value.
*
* @returns {boolean}
* @memberof Either
*/
Either.prototype.isLeft = function () {
return this.side === EitherSide.Left;
};
/**
* Returns a boolean indicating if this object represents a right value.
*
* @returns {boolean}
* @memberof Either
*/
Either.prototype.isRight = function () {
return this.side === EitherSide.Right;
};
/**
* Returns the value. Can be either left or right.
*
* @returns {(L | R)}
* @memberof Either
*/
Either.prototype.get = function () {
return this.value;
};
/**
* Returns the value of the left side. If this object is the right side,
* throws a WrongSideError.
*
* @throws {WrongSideError}
* @returns {L}
* @memberof Either
*/
Either.prototype.getLeft = function () {
if (this.isLeft()) {
return this.left;
}
throw new WrongSideError();
};
/**
* Returns the value of the right side. If this object is the left side,
* throws a WrongSideError.
*
* @throws {WrongSideError}
* @returns {R}
* @memberof Either
*/
Either.prototype.getRight = function () {
if (this.isRight()) {
return this.right;
}
throw new WrongSideError();
};
/**
* Perform an action only if the left value is present.
*
* @param {Consumer<L>} consumer
* @returns {this}
* @memberof Either
*/
Either.prototype.ifLeft = function (consumer) {
if (this.isLeft()) {
consumer(this.left);
}
return this;
};
/**
* Perform an action only if the right value is present.
*
* @param {Consumer<R>} consumer
* @returns {this}
* @memberof Either
*/
Either.prototype.ifRight = function (consumer) {
if (this.isRight()) {
consumer(this.right);
}
return this;
};
Either.prototype.reduce = function (left, right) {
if (this.isLeft()) {
return left(this.left);
}
else if (this.isRight()) {
return right(this.right);
}
};
Either.prototype.flatMap = function (left, right) {
return this.reduce(left, right);
};
Either.prototype.flatMapLeft = function (mapper) {
return this.flatMap(mapper, function (v) { return Either.right(v); });
};
Either.prototype.flatMapRight = function (mapper) {
return this.flatMap(function (v) { return Either.left(v); }, mapper);
};
Either.prototype.map = function (left, right) {
return this.flatMap(function (v) { return Either.left(left(v)); }, function (v) { return Either.right(right(v)); });
};
Either.prototype.mapLeft = function (mapper) {
return this.map(mapper, function (id) { return id; });
};
Either.prototype.mapRight = function (mapper) {
return this.map(function (id) { return id; }, mapper);
};
Either.prototype.leftOrElseGet = function (getter) {
if (this.isLeft()) {
return this.left;
}
return getter();
};
Either.prototype.leftOrElse = function (other) {
return this.leftOrElseGet(function () { return other; });
};
Either.prototype.leftOrElseThrow = function (supplier) {
if (this.isLeft()) {
this.getLeft();
}
throw supplier();
};
Either.prototype.rightOrElseGet = function (getter) {
if (this.isRight()) {
return this.right;
}
return getter();
};
Either.prototype.rightOrElse = function (other) {
return this.rightOrElseGet(function () { return other; });
};
Either.prototype.rightOrElseThrow = function (supplier) {
if (this.isRight()) {
this.getRight();
}
throw supplier();
};
return Either;
}());
exports.Either = Either;
//# sourceMappingURL=Either.js.map