Skip to content

Instantly share code, notes, and snippets.

@nirlanka
Last active May 30, 2025 08:08
Show Gist options
  • Save nirlanka/e2a1b9a590cef0f13ffee8969f47c455 to your computer and use it in GitHub Desktop.
Save nirlanka/e2a1b9a590cef0f13ffee8969f47c455 to your computer and use it in GitHub Desktop.
Pure Javascript Asserts and Type System
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pure Javascript Asserts and Type System</title>
</head>
<body style="background-color: #222; color: #fff;">
<h1>Test assert everywhere</h1>
<script>
window.__libs__ = {};
</script>
<script>
{
function assert(
/** @type {() => boolean} */ testFn,
/** @type {string} */ textOnFail,
/** @type {Array|Object} */ values,
) {
try {
const isTestPass = testFn();
if (!isTestPass)
throw Error(`Assert failure: NOT ${textOnFail}, with debug values: ${values ? JSON.stringify(values) : testFn}`);
} catch (err) {
console.error('[ASSERT FAILURE]', err);
}
}
window.__libs__.assert = assert;
}
</script>
<script>
{
const { assert } = window.__libs__;
for (const value of [
'',
"test",
12,
'true',
]) {
assert(
() => ['true', 'false'].some(x => x === value),
"a proper string version of the boolean.");
}
}
</script>
<script>
{
const { assert } = window.__libs__;
function assertType(instance, type) {
assert(
() => instance.constructor.name === type.name,
"the same type as expected [TypeBase]",
[instance, type]
);
}
class TBase {
static _PRIMITIVES = [
'number',
'string',
'object',
];
/**
* @abstract
* @type {string}
* Underlying primitive data type
*/
primitive;
_validate() {
assert(
() => TBase._PRIMITIVES.some(x => x === this.primitive),
"a valid primitive type name [TypeBase]",
[this.primitive]
);
assert(
() => (this._value !== undefined)
? (typeof this._value === this.primitive)
: true,
"a valid primitive type value [TypeBase]",
[this._value, this.primitive]
);
if (this.primitive === 'object') {
assert(
() =>
(typeof this.types === 'object')
&& Object.keys(this.types).every(k => typeof k === 'string')
&& Object.values(this.types).every(v => typeof v === 'function'),
"a valid typed object",
[this.types, this.primitive]
);
for (const k in this.types) {
assertType(this._value[k], this.types[k]);
}
}
assert(
() => this.assert(this._value),
"a valid value [TypeBase]",
[this._value],
);
}
/**
* @type {any}
*/
_value;
/** @final */
set(/** @type {any} */ v) {
this._value = v;
this._validate();
return this;
}
/**
* @final
* @returns {any} reference to the stored primitive value
*/
get() {
this._validate();
return this._value;
}
/**
* @abstract
* @returns {boolean}
*/
assert(/** @type {any} */ value) {
return true;
}
}
window.__libs__.TBase = TBase;
window.__libs__.assertType = assertType;
}
</script>
<script>
{
const { TBase, assertType } = window.__libs__;
class TNaturalNumber extends TBase {
primitive = 'number';
assert(value) {
return value >= 0;
}
}
/** @type {TNaturalNumber} */
const x1 = new TNaturalNumber().set('9');
console.log(x1);
/** @type {TNaturalNumber} */
const x2 = new TNaturalNumber().set(13);
console.log(x2);
/** @type {TNaturalNumber} */
const x3 = new TNaturalNumber().set(-4);
console.log(x3);
class TUnformattedText extends TBase {
primitive = 'string';
assert(value) {
return !!value;
}
}
/** Radio component option value **/
class TRadioOption extends TBase {
primitive = 'object';
types = {
'value': TNaturalNumber,
'label': TUnformattedText
};
}
/** @type {TRadioOption} */
const x4 = new TRadioOption().set({
value: new TNaturalNumber().set(0),
label: new TUnformattedText().set("Option 0"),
});
console.log(x4);
console.log(x4.get().value);
console.log(x4.get().value.get());
/** @type {TRadioOption} */
const x5 = new TRadioOption().set({
value: new TNaturalNumber().set(-1),
label: new TUnformattedText().set("[Please select]"),
});
console.log(x5);
console.log(x5.get().value);
console.log(x5.get().value.get());
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment