tiny-types
Version:
A tiny library that brings Tiny Types to JavaScript and TypeScript
139 lines • 4.31 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TinyType = void 0;
exports.TinyTypeOf = TinyTypeOf;
const ensure_1 = require("./ensure");
const objects_1 = require("./objects");
const predicates_1 = require("./predicates");
/**
* @desc The {@link TinyTypeOf} can be used to define simple
* single-value {@link TinyType}s on a single line.
*
* It contains a check preventing the constructor argument from being undefined (see {@link isDefined});
*
* @experimental
*
* @example
* class Username extends TinyTypeOf<string>() {}
*
* @example
* class Age extends TinyTypeOf<number>() {}
*
* @returns a dynamically created base class your tiny type can extend from
*/
function TinyTypeOf() {
return class extends TinyType {
value;
constructor(value) {
super();
this.value = value;
(0, ensure_1.ensure)(this.constructor.name, value, (0, predicates_1.isDefined)());
}
};
}
/**
* @desc The {@link TinyType} abstract class should be used as a base class for your own Tiny Types.
*
* If you want the Tiny Type to wrap a single value use the {@link TinyTypeOf} instead as it will save you some keystrokes.
*
* @example
* class FirstName extends TinyTypeOf<string>() {}
* class LastName extends TinyTypeOf<string>() {}
* class Age extends TinyTypeOf<number>() {}
*
* class Person extends TinyType {
* constructor(public readonly firstName: FirstName,
* public readonly lastName: LastName,
* public readonly age: Age,
* ) {
* super();
* }
* }
*/
class TinyType {
/**
* @desc Compares two tiny types by value
*
* @example <caption>Comparing simple types</caption>
* class Id extends TinyTypeOf<string>() {}
*
* const id = new Id(`3cc0852d-fda7-4f61-874e-0cfadbd6182a`);
*
* id.equals(id) === true
*
* @example <caption>Comparing complex types recursively</caption>
* class FirstName extends TinyTypeOf<string>() {}
* class LastName extends TinyTypeOf<string>() {}
* class Age extends TinyTypeOf<number>() {}
*
* class Person extends TinyType {
* constructor(public readonly firstName: FirstName,
* public readonly lastName: LastName,
* public readonly age: Age,
* ) {
* super();
* }
* }
*
* const p1 = new Person(new FirstName('John'), new LastName('Smith'), new Age(42)),
* p2 = new Person(new FirstName('John'), new LastName('Smith'), new Age(42));
*
* p1.equals(p2) === true
*
* @param {TinyType} another
* @returns {boolean}
*/
equals(another) {
return (0, objects_1.equal)(this, another);
}
/**
* @desc Serialises the object to its string representation
*
* @returns {string}
*/
toString() {
return (0, objects_1.stringify)(this);
}
/**
* @desc Serialises the object to a JSON representation.
*
* @example
* class FirstName extends TinyTypeOf<string>() {}
*
* const name = new FirstName('Jan');
*
* name.toJSON() === 'Jan'
*
* @example
* class FirstName extends TinyTypeOf<string>() {}
* class LastName extends TinyTypeOf<string>() {}
* class Age extends TinyTypeOf<number>() {}
*
* class Person extends TinyType {
* constructor(public readonly firstName: FirstName,
* public readonly lastName: LastName,
* public readonly age: Age,
* ) {
* super();
* }
* }
*
* const person = new Person(new FirstName('John'), new LastName('Smith'), new Age(42)),
*
* person.toJSON() === { firstName: 'John', lastName: 'Smith', age: 42 }
*
* @returns {JSONValue}
*/
toJSON() {
const fields = (0, objects_1.significantFieldsOf)(this);
if (fields.length === 1) {
return (0, objects_1.toJSON)(this[fields[0]]);
}
return fields.reduce((acc, field) => {
acc[field] = (0, objects_1.toJSON)(this[field]);
return acc;
}, {});
}
}
exports.TinyType = TinyType;
//# sourceMappingURL=TinyType.js.map