UNPKG

ts-code-contracts

Version:
258 lines (257 loc) 9.34 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; 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 }); exports.unreachable = exports.error = exports.isDefined = exports.asserts = exports.ensuresNonNullish = exports.ensures = exports.checksNonNullish = exports.checks = exports.requiresNonNullish = exports.requires = exports.AssertionError = exports.PostconditionError = exports.IllegalStateError = exports.PreconditionError = exports.ContractError = void 0; /** * An error thrown by a code contract. */ var ContractError = /** @class */ (function (_super) { __extends(ContractError, _super); function ContractError() { return _super !== null && _super.apply(this, arguments) || this; } return ContractError; }(Error)); exports.ContractError = ContractError; /** * An error thrown, if a precondition for a function or method is not met. */ var PreconditionError = /** @class */ (function (_super) { __extends(PreconditionError, _super); function PreconditionError(message) { var _this = _super.call(this, message) || this; _this.name = 'PreconditionError'; return _this; } return PreconditionError; }(ContractError)); exports.PreconditionError = PreconditionError; /** * An error thrown, if an object is an illegal state. */ var IllegalStateError = /** @class */ (function (_super) { __extends(IllegalStateError, _super); function IllegalStateError(message) { var _this = _super.call(this, message) || this; _this.name = 'IllegalStateError'; return _this; } return IllegalStateError; }(ContractError)); exports.IllegalStateError = IllegalStateError; /** * An error thrown, if a function or method could not fulfil a postcondition. */ var PostconditionError = /** @class */ (function (_super) { __extends(PostconditionError, _super); function PostconditionError(message) { var _this = _super.call(this, message) || this; _this.name = 'PostconditionError'; return _this; } return PostconditionError; }(ContractError)); exports.PostconditionError = PostconditionError; /** * An error thrown, if an assertion has failed. */ var AssertionError = /** @class */ (function (_super) { __extends(AssertionError, _super); function AssertionError(message) { var _this = _super.call(this, message) || this; _this.name = 'AssertionError'; return _this; } return AssertionError; }(ContractError)); exports.AssertionError = AssertionError; /** * Throws a `PreconditionError` if the `condition` is `false`. * @param condition the precondition that should be `true` * @param message an optional message for the error * @throws PreconditionError if the condition is `false` * @see PreconditionError * @example * function myFun(name: string) { * requires(name.length > 10, 'Name must be longer than 10 chars'); * } */ function requires(condition, message) { if (message === void 0) { message = 'Unmet precondition'; } if (!condition) { throw new PreconditionError(message); } } exports.requires = requires; /** * Returns the given value unchanged if it is not `null` or `undefined`. * Throws a `PreconditionError` otherwise. * @param value the value that should not be `null` or `undefined` * @param message an optional message for the error * @throws PreconditionError if the value is `null` or `undefined` * @see requires * @example * function myFun(name: string | null) { * const nameNonNull = requiresNonNullish(name, 'Name must be defined'); * nameNonNull.toUpperCase(); // no compiler error! * } */ function requiresNonNullish(value, message) { if (message === void 0) { message = 'Value must not be null or undefined'; } requires(isDefined(value), message); return value; } exports.requiresNonNullish = requiresNonNullish; /** * Throws a `IllegalStateError` if the `condition` is `false`. * @param condition the condition that should be `true` * @param message an optional message for the error * @throws IllegalStateError if the condition is `false` * @see IllegalStateError * @example * class Socket { * private isOpen = false; * send(data: Data) { * check(this.isOpen, 'Socket must be open'); * } * open() { * this.isOpen = true; * } * } */ function checks(condition, message) { if (message === void 0) { message = 'Callee invariant violation'; } if (!condition) { throw new IllegalStateError(message); } } exports.checks = checks; /** * Returns the given value unchanged if it is not `null` or `undefined`. * Throws a `IllegalStateError` otherwise. * @param value the value that should not be `null` or `undefined` * @param message an optional message for the error * @throws IllegalStateError if the value is `null` or `undefined` * @see checks * @example * class Socket { * data: Data | null = null; * send() { * const validData = checksNonNullish(this.data, 'Data must be available'); * validData.send(); // no compiler error! * } * } */ function checksNonNullish(value, message) { if (message === void 0) { message = 'Value must not be null or undefined'; } checks(isDefined(value), message); return value; } exports.checksNonNullish = checksNonNullish; /** * Throws a `PostconditionError` if the `condition` is `false`. * @param condition the condition that should be `true` * @param message an optional message for the error * @throws PostconditionError if the condition is `false` * @see PostconditionError * @example * function myFun() { * createPerson({ id: 0, name: 'John' }); * const entity = findById(0); // returns null if not present * return ensures(isDefined(entity), 'Failed to persist entity'); * } */ function ensures(condition, message) { if (message === void 0) { message = 'Unmet postcondition'; } if (!condition) { throw new PostconditionError(message); } } exports.ensures = ensures; /** * Returns the given value unchanged if it is not `null` or `undefined`. * Throws a `PostconditionError` otherwise. * @param value the value that must not be `null` or `undefined` * @param message an optional message for the error * @throws PostconditionError if the value is `null` or `undefined` * @see ensures * @example * function myFun(): Person { * createPerson({ id: 0, name: 'John' }); * const entity = findById(0); // returns null if not present * return ensuresNonNullish(entity, 'Failed to persist entity'); * } */ function ensuresNonNullish(value, message) { if (message === void 0) { message = 'Value must not be null or undefined'; } ensures(isDefined(value), message); return value; } exports.ensuresNonNullish = ensuresNonNullish; /** * Throws a `AssertionError` if the `condition` is `false`. * @param condition the condition that must be `true` * @param message an optional message for the error * @throws AssertionError if the condition is `false` * @see AssertionError */ function asserts(condition, message) { if (!condition) { throw new AssertionError(message); } } exports.asserts = asserts; /** * Returns `true` if the value is not `null` or `undefined`. * @param value the value to test * @example * const x: string | null = 'Hello'; * if (isDefined(x)) { * x.toLowerCase(); // no compiler error! * } */ function isDefined(value) { return value != null; } exports.isDefined = isDefined; function error(errorType, message) { throw errorType == null || typeof errorType === 'string' ? new IllegalStateError(errorType) : new errorType(message); } exports.error = error; /* eslint-enable @typescript-eslint/no-explicit-any, new-cap */ /* eslint-disable @typescript-eslint/no-unused-vars */ /** * Asserts that a code branch is unreachable. If it is, the compiler will throw a type error. * If this function is reached at runtime, an error will be thrown. * @param value a value * @param message an optional message for the error * @throws AssertionError in any case * @example * function myFun(foo: MyEnum): string { * switch(foo) { * case MyEnum.A: return 'a'; * case MyEnum.B: return 'b'; * // no compiler error if MyEnum only has A and B * default: unreachable(foo); * } * } */ function unreachable(value, message) { if (message === void 0) { message = 'Reached an unreachable case'; } throw new AssertionError(message); } exports.unreachable = unreachable;