@tolokoban/tgd
Version:
ToloGameDev library for WebGL2
351 lines • 25.4 kB
JavaScript
export function isObject(data) {
if (!data)
return false;
if (Array.isArray(data))
return false;
return typeof data === "object";
}
export function isString(data) {
return typeof data === "string";
}
export function isNumber(data) {
return typeof data === "number";
}
export function isNull(data) {
return data === null;
}
export function isFunction(data) {
return typeof data === "function";
}
export function isUndefined(data) {
return data === undefined;
}
export function isBoolean(data) {
return typeof data === "boolean";
}
export function isArrayBuffer(data) {
if (!data)
return false;
return data instanceof ArrayBuffer;
}
export function isArrayBufferView(data) {
if (!data)
return false;
return ArrayBuffer.isView(data);
}
export function isBufferSource(data) {
return isArrayBuffer(data) || isArrayBufferView(data);
}
export function isStringArray(data) {
if (!Array.isArray(data))
return false;
// eslint-disable-next-line no-restricted-syntax
for (const item of data) {
if (!isString(item))
return false;
}
return true;
}
export function assertNumber(data, name = "data") {
if (!isNumber(data)) {
throw new TypeError(`${name} was expected to be a number but we got ${typeof data}!`);
}
}
export function assertString(data, name = "data") {
if (!isString(data)) {
throw new TypeError(`${name} was expected to be a string but we got ${typeof data}!`);
}
}
export function assertOptionalString(data, name = "data") {
if (data && !isString(data)) {
throw new TypeError(`${name} was expected to be a string but we got ${typeof data}!`);
}
}
export function assertBoolean(data, name = "data") {
if (!isBoolean(data)) {
throw new TypeError(`${name} was expected to be a boolean but we got ${typeof data}!`);
}
}
export function assertObject(data, name = "data") {
if (!isObject(data)) {
throw new TypeError(`${name} was expected to be an object but we got ${typeof data}!`);
}
}
export function assertArray(data, name = "data") {
if (!Array.isArray(data)) {
throw new TypeError(`${name} was expected to be an Array but we got ${typeof data}!`);
}
}
export function assertArrayBuffer(data, name = "data") {
if (!isArrayBuffer(data)) {
throw new TypeError(`${name} was expected to be an ArrayBuffer but we got ${typeof data}!`);
}
}
export function assertOptionalArrayBuffer(data, name = "data") {
if (data && !isArrayBuffer(data)) {
throw new TypeError(`${name} was expected to be an ArrayBuffer but we got ${typeof data}!`);
}
}
export function isType(data, type, logErrors = null) {
return isType$(data, type, logErrors);
}
export function isType$(data, type, logErrors = null) {
try {
assertType$(data, type);
return true;
}
catch (error) {
if (logErrors) {
console.error("[Invalid type]", logErrors);
console.error(data);
console.debug(error);
}
return false;
}
}
export function assertType(data, type, prefix = "data") {
return assertType$(data, type, prefix);
}
export function assertType$(data, type, prefix = "data") {
if (typeof type === "function")
return assertType$(data, type(), prefix);
if (type === "unknown")
return;
if (type === "null") {
if (data !== null) {
throw new TypeError(`Expected ${prefix} to be a null and not a ${prettyTypeof(data)}!`);
}
return;
}
if (typeof type === "string") {
if (typeof data !== type) {
throw new TypeError(`Expected ${prefix} to be a ${type} and not a ${prettyTypeof(data)}!`);
}
return;
}
if (Array.isArray(type)) {
const [kind] = type;
switch (kind) {
case "array":
assertTypeArray(data, prefix, type);
return;
case "map":
assertTypeMap(data, prefix, type);
return;
case "?":
assertTypeOptional(data, prefix, type);
return;
case "|":
assertTypeAlternative(data, prefix, type);
return;
case "tuple":
assertTypeTuple(data, prefix, type);
return;
case "tuple...":
assertTypeTupleWithRest(data, prefix, type);
return;
case "partial":
assertTypePartial(data, prefix, type);
return;
case "literal":
assertTypeLiteral(data, prefix, type);
return;
case "custom":
assertTypeCustom(data, prefix, type);
return;
default:
throw new TypeError(`Don't know how to create a type guard for this kind of type: ${JSON.stringify(type)}`);
}
}
if (typeof data !== "object")
throw new TypeError(`Expected ${prefix} to be an object and not a ${prettyTypeof(data)}!`);
const obj = data;
for (const name of Object.keys(type)) {
if (typeof name !== "string")
continue;
assertType$(obj[name], type[name], `${prefix}.${name}`);
}
}
function assertTypeTuple(data, prefix, [, ...types]) {
assertArray(data);
if (types.length > data.length) {
throw new TypeError(`Expected ${prefix}'s length to be at least ${types.length} and not ${data.length}!`);
}
for (let i = 0; i < types.length; i++) {
const type = types[i];
assertType$(data[i], type, `${prefix}[${i}]`);
}
}
function assertTypeTupleWithRest(data, prefix, [, ...types]) {
const last = types.length - 1;
const fixTypes = types.slice(0, last);
assertTypeTuple(data, prefix, ["tuple", ...fixTypes]);
const rest = types[last];
for (let i = last; i < data.length; i++) {
assertType$(data[i], rest, `${prefix}[${i}]`);
}
}
function assertTypePartial(data, prefix, [, type]) {
assertObject(data, prefix);
for (const name of Object.keys(type)) {
if (typeof name !== "string")
continue;
const attrib = data[name];
if (attrib !== undefined) {
assertType$(attrib, type[name], `${prefix}.${name}`);
}
}
}
function assertTypeArray(data, prefix, type) {
if (!Array.isArray(data))
throw new TypeError(`Expected ${prefix} to be an array and not a ${prettyTypeof(data)}!`);
const [, subType, constraints] = type;
if (constraints) {
const len = data.length;
if (isNumber(constraints)) {
if (len !== constraints) {
throw new TypeError(`Expected ${prefix}'s length to be ${constraints} and not ${len}!`);
}
}
else {
const { min, max } = constraints;
if (isNumber(min) && len < min) {
throw new TypeError(`Expected ${prefix}'s MIN length to be ${min} and not ${len}!`);
}
if (isNumber(max) && len > max) {
throw new TypeError(`Expected ${prefix}'s MAX length to be ${max} and not ${len}!`);
}
}
}
for (let i = 0; i < data.length; i += 1) {
assertType$(data[i], subType, `${prefix}[${i}]`);
}
}
function assertTypeMap(data, prefix, type) {
if (!isObject(data))
throw new TypeError(`Expected ${prefix} to be an object and not a ${prettyTypeof(data)}!`);
const [, subType] = type;
for (const key of Object.keys(data)) {
if (typeof key === "string") {
assertType$(data[key], subType, `${prefix}[${key}]`);
}
}
}
function assertTypeOptional(data, prefix, type) {
if (data === undefined)
return;
const [, optionalType] = type;
assertType$(data, optionalType, prefix);
}
function assertTypeAlternative(data, prefix, type) {
const [, ...altTypes] = type;
if (altTypes.length === 0)
throw new TypeError(`No type has been defined for this alternative: ${JSON.stringify(type)}!`);
const exceptions = [];
for (const altType of altTypes) {
try {
assertType$(data, altType, prefix);
return;
}
catch (ex) {
if (ex instanceof Error)
exceptions.push(ex);
}
}
throw new TypeError(`All alternatives failed!${exceptions.map((ex) => `\n${ex.message}`)}`);
}
function assertTypeLiteral(data, prefix, type) {
const [, ...literals] = type;
for (const literal of literals) {
if (data === literal)
return;
}
throw new TypeError(`Expected ${prefix} to be a literal (${literals
.map((item) => `"${item}"`)
.join(" | ")}) and not a ${prettyTypeof(data)}!`);
}
function assertTypeCustom(data, prefix, [, typeGuard]) {
// Custom type guard.
if (!typeGuard(data)) {
throw new TypeError(`Expected ${typeGuard.name}(${prefix}) to return true!`);
}
return;
}
/**
* Basically, this function checks a `data` against a `type` and returns a `defaultValue`
* if `data` is not of the expected type.
*
* But if the `defaultValue` is a function returning the expected `type`, then `ensureType`
* can be use to update old data that you have retrieved from local storage, for example.
*
* @example
* ```
* interface Complex { r: number, i: number }
* const complex = ensureType<Complex>(data, {r: "number", i: "number"}, { r: 1, i: 0 })
* ```
*
* @example
* ```
* interpace PersonVersion1 {
* name: string
* female: boolean
* }
* interpace PersonVersion2 {
* name: string
* gender: "male" | "female" | "nonbinary" | "unknown"
* }
*
* const data = JSON.parse(LocalStorate.getItem("person") ?? "null")
* const TypePersonVersion1 = {
* name: "string",
* female: "boolean"
* }
* const TypePersonVersion2 = {
* name: "string",
* gender: ["literal", "male", "female", "nonbinary", "unknown"]
* }
* const person = ensureType<PersonVersion2>(
* data,
* TypePersonVersion2,
* (value: unknown) => {
* if (isType<PersonVersion2>(value, TypePersonVersion2)) {
* return value
* }
* if (isType<PersonVersion1>(value, TypePersonVersion1)) {
* return {
* name: value.name,
* gender: value.female === true ? "female" : "unknown"
* }
* }
* return { name: "Anonymous", gender: "unknown" }
* }
* )
* ```
*
* @param data Value with unknown type.
* @param type The type to check against.
* @param defaultValue If the type doesn't check, we can return `defaultValue`, or call it if this is a function.
* @returns A value that is of the expected type.
*/
export function ensureType(data, type, defaultValue) {
if (isType$(data, type))
return data;
return isType$(defaultValue, type) ? defaultValue : defaultValue(data);
}
export function ensureBoolean(data, defaultValue) {
return ensureType(data, "boolean", defaultValue);
}
export function ensureNumber(data, defaultValue) {
return ensureType(data, "number", defaultValue);
}
export function ensureString(data, defaultValue) {
return ensureType(data, "string", defaultValue);
}
function prettyTypeof(data) {
if (data === null)
return "null";
if (typeof data === "function")
return `function ${data.name ?? ""}()`;
return typeof data;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3VhcmRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3R5cGVzL2d1YXJkcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxNQUFNLFVBQVUsUUFBUSxDQUFDLElBQWE7SUFDbEMsSUFBSSxDQUFDLElBQUk7UUFBRSxPQUFPLEtBQUssQ0FBQTtJQUN2QixJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDO1FBQUUsT0FBTyxLQUFLLENBQUE7SUFDckMsT0FBTyxPQUFPLElBQUksS0FBSyxRQUFRLENBQUE7QUFDbkMsQ0FBQztBQUVELE1BQU0sVUFBVSxRQUFRLENBQUMsSUFBYTtJQUNsQyxPQUFPLE9BQU8sSUFBSSxLQUFLLFFBQVEsQ0FBQTtBQUNuQyxDQUFDO0FBRUQsTUFBTSxVQUFVLFFBQVEsQ0FBQyxJQUFhO0lBQ2xDLE9BQU8sT0FBTyxJQUFJLEtBQUssUUFBUSxDQUFBO0FBQ25DLENBQUM7QUFFRCxNQUFNLFVBQVUsTUFBTSxDQUFDLElBQWE7SUFDaEMsT0FBTyxJQUFJLEtBQUssSUFBSSxDQUFBO0FBQ3hCLENBQUM7QUFFRCxNQUFNLFVBQVUsVUFBVSxDQUFDLElBQWE7SUFDcEMsT0FBTyxPQUFPLElBQUksS0FBSyxVQUFVLENBQUE7QUFDckMsQ0FBQztBQUVELE1BQU0sVUFBVSxXQUFXLENBQUMsSUFBYTtJQUNyQyxPQUFPLElBQUksS0FBSyxTQUFTLENBQUE7QUFDN0IsQ0FBQztBQUVELE1BQU0sVUFBVSxTQUFTLENBQUMsSUFBYTtJQUNuQyxPQUFPLE9BQU8sSUFBSSxLQUFLLFNBQVMsQ0FBQTtBQUNwQyxDQUFDO0FBRUQsTUFBTSxVQUFVLGFBQWEsQ0FBQyxJQUFhO0lBQ3ZDLElBQUksQ0FBQyxJQUFJO1FBQUUsT0FBTyxLQUFLLENBQUE7SUFDdkIsT0FBTyxJQUFJLFlBQVksV0FBVyxDQUFBO0FBQ3RDLENBQUM7QUFFRCxNQUFNLFVBQVUsaUJBQWlCLENBQUMsSUFBYTtJQUMzQyxJQUFJLENB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