UNPKG

isaacscript-common

Version:

Helper functions and features for IsaacScript mods.

227 lines (226 loc) • 7.8 kB
"use strict"; /** * Consider the following code that uses a number enum: * * ```ts * enum MyEnum { * Value1, * } * * function asMyEnum(num: number): MyEnum {} * * declare const something: unknown; * * const foo = something as MyEnum; // no error * const bar: MyEnum = something; // error * const baz = asMyEnum(something); // error * ``` * * Here, using `as` does not give an error because TypeScript allows you to assert a type to a * supertype or a subtype. Thus, using `as` to perform a type assertion is not as safe as using a * variable declaration or a helper function. However, if we use a variable declaration, then the * `complete/strict-enums` rule is triggered, which requires suppressing the lint rule with a `// * eslint-disable-next-line`. Thus, the safest and more concise way to do a type assertion is to use * a helper function. * * This file contains helper functions for various number enums that might require type assertions. * It also contains helper functions for run-time type checks. * * @module */ Object.defineProperty(exports, "__esModule", { value: true }); exports.asCardType = asCardType; exports.asCollectibleType = asCollectibleType; exports.asFloat = asFloat; exports.asInt = asInt; exports.asLevelStage = asLevelStage; exports.asNPCState = asNPCState; exports.asNumber = asNumber; exports.asPillColor = asPillColor; exports.asPillEffect = asPillEffect; exports.asPlayerType = asPlayerType; exports.asRoomType = asRoomType; exports.asString = asString; exports.asTrinketType = asTrinketType; exports.isBoolean = isBoolean; exports.isFunction = isFunction; exports.isInteger = isInteger; exports.isNumber = isNumber; exports.isPrimitive = isPrimitive; exports.isString = isString; exports.isTable = isTable; exports.isUserdata = isUserdata; exports.parseIntSafe = parseIntSafe; /** * Helper function to safely cast an `int` to a `CardType`. (This is better than using the `as` * TypeScript keyword to do a type assertion, since that can obfuscate compiler errors. ) * * This is useful to satisfy the "complete/strict-enums" ESLint rule. */ function asCardType(num) { return num; } /** * Helper function to safely cast an `int` to a `CollectibleType`. (This is better than using the * `as` TypeScript keyword to do a type assertion, since that can obfuscate compiler errors. ) * * This is useful to satisfy the "complete/strict-enums" ESLint rule. */ function asCollectibleType(num) { return num; } /** * Helper function to safely cast an enum to an `int`. (This is better than using the `as` * TypeScript keyword to do a type assertion, since that can obfuscate compiler errors. ) * * This is useful to satisfy the "complete/strict-enums" ESLint rule. */ function asFloat(num) { return num; } /** * Helper function to safely cast an enum to an `int`. (This is better than using the `as` * TypeScript keyword to do a type assertion, since that can obfuscate compiler errors. ) * * This is useful to satisfy the "complete/strict-enums" ESLint rule. */ function asInt(num) { return num; } /** * Helper function to safely cast an `int` to a `LevelStage`. (This is better than using the `as` * TypeScript keyword to do a type assertion, since that can obfuscate compiler errors. ) * * This is useful to satisfy the "complete/strict-enums" ESLint rule. */ function asLevelStage(num) { return num; } /** * Helper function to safely cast an `int` to a `NPCState`. (This is better than using the `as` * TypeScript keyword to do a type assertion, since that can obfuscate compiler errors. ) * * This is useful to satisfy the "complete/strict-enums" ESLint rule. */ function asNPCState(num) { return num; } /** * Helper function to safely cast an enum to a `number`. (This is better than using the `as` * TypeScript keyword to do a type assertion, since that can obfuscate compiler errors. ) * * This is useful to satisfy the "complete/strict-enums" ESLint rule. */ function asNumber(num) { return num; } /** * Helper function to safely cast an `int` to a `PillColor`. (This is better than using the `as` * TypeScript keyword to do a type assertion, since that can obfuscate compiler errors. ) * * This is useful to satisfy the "complete/strict-enums" ESLint rule. */ function asPillColor(num) { return num; } /** * Helper function to safely cast an `int` to a `PillEffect`. (This is better than using the `as` * TypeScript keyword to do a type assertion, since that can obfuscate compiler errors. ) * * This is useful to satisfy the "complete/strict-enums" ESLint rule. */ function asPillEffect(num) { return num; } /** * Helper function to safely cast an `int` to a `PlayerType`. (This is better than using the `as` * TypeScript keyword to do a type assertion, since that can obfuscate compiler errors. ) * * This is useful to satisfy the "complete/strict-enums" ESLint rule. */ function asPlayerType(num) { return num; } /** * Helper function to safely cast an `int` to a `RoomType`. (This is better than using the `as` * TypeScript keyword to do a type assertion, since that can obfuscate compiler errors. ) * * This is useful to satisfy the "complete/strict-enums" ESLint rule. */ function asRoomType(num) { return num; } /** * Helper function to safely cast an enum to a `string`. (This is better than using the `as` * TypeScript keyword to do a type assertion, since that can obfuscate compiler errors. ) * * This is useful to satisfy the "complete/strict-enums" ESLint rule. */ function asString(str) { return str; } /** * Helper function to safely cast an `int` to a `TrinketType`. (This is better than using the `as` * TypeScript keyword to do a type assertion, since that can obfuscate compiler errors. ) * * This is useful to satisfy the "complete/strict-enums" ESLint rule. */ function asTrinketType(num) { return num; } function isBoolean(variable) { return typeof variable === "boolean"; } // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type function isFunction(variable) { return typeof variable === "function"; } function isInteger(variable) { if (!isNumber(variable)) { return false; } return variable === Math.floor(variable); } function isNumber(variable) { return typeof variable === "number"; } /** Helper function to detect if a variable is a boolean, number, or string. */ function isPrimitive(variable) { const variableType = typeof variable; return (variableType === "boolean" || variableType === "number" || variableType === "string"); } function isString(variable) { return typeof variable === "string"; } function isTable(variable) { // We cannot use `typeof` here since "table" is not a JavaScript type. return type(variable) === "table"; } function isUserdata(variable) { // We cannot use `typeof` here since "userdata" is not a JavaScript type. return type(variable) === "userdata"; } /** * Helper function to convert a string to an integer. Returns undefined if the string is not an * integer. * * Under the hood, this uses the built-in `tonumber` and `math.floor` functions. * * This is named `parseIntSafe` in order to match the helper function from `complete-common`. */ function parseIntSafe(string) { if (!isString(string)) { return undefined; } // - The `tonumber` function correctly deals with leading and trailing whitespace. // - The `tonumber` function correctly deals with a mix of numbers and letters. (e.g. `1a` returns // undefined.) const number = tonumber(string); if (number === undefined) { return undefined; } const flooredNumber = Math.floor(number); return number === flooredNumber ? flooredNumber : undefined; }