mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-08-06 23:49:26 +02:00
[Dev] Moved type helpers to separate directory; (#6123)
* [Dev] Moved type helpers to separate directory; renamed `EnumValues` to `ObjectValues` and enforced usage * Update tsconfig.json Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * Fixed import issue * Updated documentation slightly --------- Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> Co-authored-by: Dean <69436131+emdeann@users.noreply.github.com>
This commit is contained in:
parent
17eeceb4f3
commit
1ae69a4183
@ -1,6 +1,6 @@
|
|||||||
import type { ArenaTagTypeMap } from "#data/arena-tag";
|
import type { ArenaTagTypeMap } from "#data/arena-tag";
|
||||||
import type { ArenaTagType } from "#enums/arena-tag-type";
|
import type { ArenaTagType } from "#enums/arena-tag-type";
|
||||||
import type { NonFunctionProperties } from "./type-helpers";
|
import type { NonFunctionProperties } from "#types/type-helpers";
|
||||||
|
|
||||||
/** Subset of {@linkcode ArenaTagType}s that apply some negative effect to pokemon that switch in ({@link https://bulbapedia.bulbagarden.net/wiki/List_of_moves_that_cause_entry_hazards#List_of_traps | entry hazards} and Imprison. */
|
/** Subset of {@linkcode ArenaTagType}s that apply some negative effect to pokemon that switch in ({@link https://bulbapedia.bulbagarden.net/wiki/List_of_moves_that_cause_entry_hazards#List_of_traps | entry hazards} and Imprison. */
|
||||||
export type ArenaTrapTagType =
|
export type ArenaTrapTagType =
|
||||||
|
@ -1,18 +1,14 @@
|
|||||||
|
import type { ObjectValues } from "#types/type-helpers";
|
||||||
|
|
||||||
/** Union type accepting any TS Enum or `const object`, with or without reverse mapping. */
|
/** Union type accepting any TS Enum or `const object`, with or without reverse mapping. */
|
||||||
export type EnumOrObject = Record<string | number, string | number>;
|
export type EnumOrObject = Record<string | number, string | number>;
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility type to extract the enum values from a `const object`,
|
|
||||||
* or convert an `enum` interface produced by `typeof Enum` into the union type representing its values.
|
|
||||||
*/
|
|
||||||
export type EnumValues<E> = E[keyof E];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generic type constraint representing a TS numeric enum with reverse mappings.
|
* Generic type constraint representing a TS numeric enum with reverse mappings.
|
||||||
* @example
|
* @example
|
||||||
* TSNumericEnum<typeof WeatherType>
|
* TSNumericEnum<typeof WeatherType>
|
||||||
*/
|
*/
|
||||||
export type TSNumericEnum<T extends EnumOrObject> = number extends EnumValues<T> ? T : never;
|
export type TSNumericEnum<T extends EnumOrObject> = number extends ObjectValues<T> ? T : never;
|
||||||
|
|
||||||
/** Generic type constraint representing a non reverse-mapped TS enum or `const object`. */
|
/** Generic type constraint representing a non reverse-mapped TS enum or `const object`. */
|
||||||
export type NormalEnum<T extends EnumOrObject> = Exclude<T, TSNumericEnum<T>>;
|
export type NormalEnum<T extends EnumOrObject> = Exclude<T, TSNumericEnum<T>>;
|
@ -6,8 +6,6 @@
|
|||||||
import type { AbAttr } from "#abilities/ability";
|
import type { AbAttr } from "#abilities/ability";
|
||||||
// biome-ignore-end lint/correctness/noUnusedImports: Used in a tsdoc comment
|
// biome-ignore-end lint/correctness/noUnusedImports: Used in a tsdoc comment
|
||||||
|
|
||||||
import type { EnumValues } from "#types/enum-types";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exactly matches the type of the argument, preventing adding additional properties.
|
* Exactly matches the type of the argument, preventing adding additional properties.
|
||||||
*
|
*
|
||||||
@ -37,16 +35,25 @@ export type Mutable<T> = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Type helper to obtain the keys associated with a given value inside a `const object`.
|
* Type helper to obtain the keys associated with a given value inside an object.
|
||||||
* @typeParam O - The type of the object
|
* @typeParam O - The type of the object
|
||||||
* @typeParam V - The type of one of O's values
|
* @typeParam V - The type of one of O's values
|
||||||
*/
|
*/
|
||||||
export type InferKeys<O extends Record<keyof any, unknown>, V extends EnumValues<O>> = {
|
export type InferKeys<O extends object, V extends ObjectValues<O>> = {
|
||||||
[K in keyof O]: O[K] extends V ? K : never;
|
[K in keyof O]: O[K] extends V ? K : never;
|
||||||
}[keyof O];
|
}[keyof O];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Type helper that matches any `Function` type. Equivalent to `Function`, but will not raise a warning from Biome.
|
* Utility type to obtain the values of a given object. \
|
||||||
|
* Functions similar to `keyof E`, except producing the values instead of the keys.
|
||||||
|
* @remarks
|
||||||
|
* This can be used to convert an `enum` interface produced by `typeof Enum` into the union type representing its members.
|
||||||
|
*/
|
||||||
|
export type ObjectValues<E extends object> = E[keyof E];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type helper that matches any `Function` type.
|
||||||
|
* Equivalent to `Function`, but will not raise a warning from Biome.
|
||||||
*/
|
*/
|
||||||
export type AnyFn = (...args: any[]) => any;
|
export type AnyFn = (...args: any[]) => any;
|
||||||
|
|
||||||
@ -65,6 +72,7 @@ export type NonFunctionProperties<T> = {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Type helper to extract out non-function properties from a type, recursively applying to nested properties.
|
* Type helper to extract out non-function properties from a type, recursively applying to nested properties.
|
||||||
|
* This can be used to mimic the effects of JSON serialization and de-serialization on a given type.
|
||||||
*/
|
*/
|
||||||
export type NonFunctionPropertiesRecursive<Class> = {
|
export type NonFunctionPropertiesRecursive<Class> = {
|
||||||
[K in keyof Class as Class[K] extends AnyFn ? never : K]: Class[K] extends Array<infer U>
|
[K in keyof Class as Class[K] extends AnyFn ? never : K]: Class[K] extends Array<infer U>
|
@ -3,6 +3,7 @@
|
|||||||
import type { Pokemon } from "#field/pokemon";
|
import type { Pokemon } from "#field/pokemon";
|
||||||
import type { ModifierConstructorMap } from "#modifiers/modifier";
|
import type { ModifierConstructorMap } from "#modifiers/modifier";
|
||||||
import type { ModifierType, WeightedModifierType } from "#modifiers/modifier-type";
|
import type { ModifierType, WeightedModifierType } from "#modifiers/modifier-type";
|
||||||
|
import type { ObjectValues } from "#types/type-helpers";
|
||||||
|
|
||||||
export type ModifierTypeFunc = () => ModifierType;
|
export type ModifierTypeFunc = () => ModifierType;
|
||||||
export type WeightedModifierTypeWeightFunc = (party: Pokemon[], rerollCount?: number) => number;
|
export type WeightedModifierTypeWeightFunc = (party: Pokemon[], rerollCount?: number) => number;
|
||||||
@ -19,7 +20,7 @@ export type ModifierInstanceMap = {
|
|||||||
/**
|
/**
|
||||||
* Union type of all modifier constructors.
|
* Union type of all modifier constructors.
|
||||||
*/
|
*/
|
||||||
export type ModifierClass = ModifierConstructorMap[keyof ModifierConstructorMap];
|
export type ModifierClass = ObjectValues<ModifierConstructorMap>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Union type of all modifier names as strings.
|
* Union type of all modifier names as strings.
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import type { PhaseConstructorMap } from "#app/phase-manager";
|
import type { PhaseConstructorMap } from "#app/phase-manager";
|
||||||
|
import type { ObjectValues } from "#types/type-helpers";
|
||||||
|
|
||||||
// Intentionally export the types of everything in phase-manager, as this file is meant to be
|
// Intentionally export the types of everything in phase-manager, as this file is meant to be
|
||||||
// the centralized place for type definitions for the phase system.
|
// the centralized place for type definitions for the phase system.
|
||||||
@ -17,7 +18,7 @@ export type PhaseMap = {
|
|||||||
/**
|
/**
|
||||||
* Union type of all phase constructors.
|
* Union type of all phase constructors.
|
||||||
*/
|
*/
|
||||||
export type PhaseClass = PhaseConstructorMap[keyof PhaseConstructorMap];
|
export type PhaseClass = ObjectValues<PhaseConstructorMap>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Union type of all phase names as strings.
|
* Union type of all phase names as strings.
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import type { ObjectValues } from "#types/type-helpers";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Not to be confused with an Ability Attribute.
|
* Not to be confused with an Ability Attribute.
|
||||||
* This is an object literal storing the slot that an ability can occupy.
|
* This is an object literal storing the slot that an ability can occupy.
|
||||||
@ -8,4 +10,4 @@ export const AbilityAttr = Object.freeze({
|
|||||||
ABILITY_HIDDEN: 4,
|
ABILITY_HIDDEN: 4,
|
||||||
});
|
});
|
||||||
|
|
||||||
export type AbilityAttr = typeof AbilityAttr[keyof typeof AbilityAttr];
|
export type AbilityAttr = ObjectValues<typeof AbilityAttr>;
|
@ -1,3 +1,5 @@
|
|||||||
|
import type { ObjectValues } from "#types/type-helpers";
|
||||||
|
|
||||||
export const DexAttr = Object.freeze({
|
export const DexAttr = Object.freeze({
|
||||||
NON_SHINY: 1n,
|
NON_SHINY: 1n,
|
||||||
SHINY: 2n,
|
SHINY: 2n,
|
||||||
@ -8,4 +10,4 @@ export const DexAttr = Object.freeze({
|
|||||||
VARIANT_3: 64n,
|
VARIANT_3: 64n,
|
||||||
DEFAULT_FORM: 128n,
|
DEFAULT_FORM: 128n,
|
||||||
});
|
});
|
||||||
export type DexAttr = typeof DexAttr[keyof typeof DexAttr];
|
export type DexAttr = ObjectValues<typeof DexAttr>;
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
|
import type { ObjectValues } from "#types/type-helpers";
|
||||||
|
|
||||||
export const GachaType = Object.freeze({
|
export const GachaType = Object.freeze({
|
||||||
MOVE: 0,
|
MOVE: 0,
|
||||||
LEGENDARY: 1,
|
LEGENDARY: 1,
|
||||||
SHINY: 2
|
SHINY: 2
|
||||||
});
|
});
|
||||||
|
|
||||||
export type GachaType = typeof GachaType[keyof typeof GachaType];
|
export type GachaType = ObjectValues<typeof GachaType>;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import type { ObjectValues } from "#types/type-helpers";
|
||||||
|
|
||||||
/** The result of a hit check calculation */
|
/** The result of a hit check calculation */
|
||||||
export const HitCheckResult = {
|
export const HitCheckResult = {
|
||||||
/** Hit checks haven't been evaluated yet in this pass */
|
/** Hit checks haven't been evaluated yet in this pass */
|
||||||
@ -20,4 +22,4 @@ export const HitCheckResult = {
|
|||||||
ERROR: 8,
|
ERROR: 8,
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export type HitCheckResult = typeof HitCheckResult[keyof typeof HitCheckResult];
|
export type HitCheckResult = ObjectValues<typeof HitCheckResult>;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import type { EnumOrObject, EnumValues, NormalEnum, TSNumericEnum } from "#app/@types/enum-types";
|
import type { EnumOrObject, NormalEnum, TSNumericEnum } from "#types/enum-types";
|
||||||
import type { InferKeys } from "#app/@types/type-helpers";
|
import type { InferKeys, ObjectValues } from "#types/type-helpers";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the string keys of an Enum object, excluding reverse-mapped numbers.
|
* Return the string keys of an Enum object, excluding reverse-mapped numbers.
|
||||||
@ -61,7 +61,7 @@ export function getEnumValues<E extends EnumOrObject>(enumType: TSNumericEnum<E>
|
|||||||
* If multiple keys map to the same value, the first one (in insertion order) will be retrieved,
|
* If multiple keys map to the same value, the first one (in insertion order) will be retrieved,
|
||||||
* but the return type will be the union of ALL their corresponding keys.
|
* but the return type will be the union of ALL their corresponding keys.
|
||||||
*/
|
*/
|
||||||
export function enumValueToKey<T extends EnumOrObject, V extends EnumValues<T>>(
|
export function enumValueToKey<T extends EnumOrObject, V extends ObjectValues<T>>(
|
||||||
object: NormalEnum<T>,
|
object: NormalEnum<T>,
|
||||||
val: V,
|
val: V,
|
||||||
): InferKeys<T, V> {
|
): InferKeys<T, V> {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import type { EnumOrObject, EnumValues, NormalEnum, TSNumericEnum } from "#app/@types/enum-types";
|
|
||||||
import type { enumValueToKey, getEnumKeys, getEnumValues } from "#app/utils/enums";
|
import type { enumValueToKey, getEnumKeys, getEnumValues } from "#app/utils/enums";
|
||||||
|
import type { EnumOrObject, NormalEnum, TSNumericEnum } from "#types/enum-types";
|
||||||
|
import type { ObjectValues } from "#types/type-helpers";
|
||||||
import { describe, expectTypeOf, it } from "vitest";
|
import { describe, expectTypeOf, it } from "vitest";
|
||||||
|
|
||||||
enum testEnumNum {
|
enum testEnumNum {
|
||||||
@ -16,21 +17,33 @@ const testObjNum = { testON1: 1, testON2: 2 } as const;
|
|||||||
|
|
||||||
const testObjString = { testOS1: "apple", testOS2: "banana" } as const;
|
const testObjString = { testOS1: "apple", testOS2: "banana" } as const;
|
||||||
|
|
||||||
describe("Enum Type Helpers", () => {
|
interface testObject {
|
||||||
describe("EnumValues", () => {
|
key_1: "1";
|
||||||
it("should go from enum object type to value type", () => {
|
key_2: "2";
|
||||||
expectTypeOf<EnumValues<typeof testEnumNum>>().toEqualTypeOf<testEnumNum>();
|
key_3: "3";
|
||||||
expectTypeOf<EnumValues<typeof testEnumNum>>().branded.toEqualTypeOf<1 | 2>();
|
}
|
||||||
|
|
||||||
expectTypeOf<EnumValues<typeof testEnumString>>().toEqualTypeOf<testEnumString>();
|
describe("Enum Type Helpers", () => {
|
||||||
expectTypeOf<EnumValues<typeof testEnumString>>().toEqualTypeOf<testEnumString.testS1 | testEnumString.testS2>();
|
describe("ObjectValues", () => {
|
||||||
expectTypeOf<EnumValues<typeof testEnumString>>().toMatchTypeOf<"apple" | "banana">();
|
it("should produce a union of an object's values", () => {
|
||||||
|
expectTypeOf<ObjectValues<testObject>>().toEqualTypeOf<"1" | "2" | "3">();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should go from enum object type to value type", () => {
|
||||||
|
expectTypeOf<ObjectValues<typeof testEnumNum>>().toEqualTypeOf<testEnumNum>();
|
||||||
|
expectTypeOf<ObjectValues<typeof testEnumNum>>().branded.toEqualTypeOf<1 | 2>();
|
||||||
|
|
||||||
|
expectTypeOf<ObjectValues<typeof testEnumString>>().toEqualTypeOf<testEnumString>();
|
||||||
|
expectTypeOf<ObjectValues<typeof testEnumString>>().toEqualTypeOf<
|
||||||
|
testEnumString.testS1 | testEnumString.testS2
|
||||||
|
>();
|
||||||
|
|
||||||
|
expectTypeOf<ObjectValues<typeof testEnumString>>().toExtend<"apple" | "banana">();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should produce union of const object values as type", () => {
|
it("should produce union of const object values as type", () => {
|
||||||
expectTypeOf<EnumValues<typeof testObjNum>>().toEqualTypeOf<1 | 2>();
|
expectTypeOf<ObjectValues<typeof testObjNum>>().toEqualTypeOf<1 | 2>();
|
||||||
|
expectTypeOf<ObjectValues<typeof testObjString>>().toEqualTypeOf<"apple" | "banana">();
|
||||||
expectTypeOf<EnumValues<typeof testObjString>>().toEqualTypeOf<"apple" | "banana">();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -38,7 +51,6 @@ describe("Enum Type Helpers", () => {
|
|||||||
it("should match numeric enums", () => {
|
it("should match numeric enums", () => {
|
||||||
expectTypeOf<TSNumericEnum<typeof testEnumNum>>().toEqualTypeOf<typeof testEnumNum>();
|
expectTypeOf<TSNumericEnum<typeof testEnumNum>>().toEqualTypeOf<typeof testEnumNum>();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should not match string enums or const objects", () => {
|
it("should not match string enums or const objects", () => {
|
||||||
expectTypeOf<TSNumericEnum<typeof testEnumString>>().toBeNever();
|
expectTypeOf<TSNumericEnum<typeof testEnumString>>().toBeNever();
|
||||||
expectTypeOf<TSNumericEnum<typeof testObjNum>>().toBeNever();
|
expectTypeOf<TSNumericEnum<typeof testObjNum>>().toBeNever();
|
||||||
@ -59,19 +71,19 @@ describe("Enum Type Helpers", () => {
|
|||||||
|
|
||||||
describe("EnumOrObject", () => {
|
describe("EnumOrObject", () => {
|
||||||
it("should match any enum or const object", () => {
|
it("should match any enum or const object", () => {
|
||||||
expectTypeOf<typeof testEnumNum>().toMatchTypeOf<EnumOrObject>();
|
expectTypeOf<typeof testEnumNum>().toExtend<EnumOrObject>();
|
||||||
expectTypeOf<typeof testEnumString>().toMatchTypeOf<EnumOrObject>();
|
expectTypeOf<typeof testEnumString>().toExtend<EnumOrObject>();
|
||||||
expectTypeOf<typeof testObjNum>().toMatchTypeOf<EnumOrObject>();
|
expectTypeOf<typeof testObjNum>().toExtend<EnumOrObject>();
|
||||||
expectTypeOf<typeof testObjString>().toMatchTypeOf<EnumOrObject>();
|
expectTypeOf<typeof testObjString>().toExtend<EnumOrObject>();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should not match an enum value union w/o typeof", () => {
|
it("should not match an enum value union w/o typeof", () => {
|
||||||
expectTypeOf<testEnumNum>().not.toMatchTypeOf<EnumOrObject>();
|
expectTypeOf<testEnumNum>().not.toExtend<EnumOrObject>();
|
||||||
expectTypeOf<testEnumString>().not.toMatchTypeOf<EnumOrObject>();
|
expectTypeOf<testEnumString>().not.toExtend<EnumOrObject>();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should be equivalent to `TSNumericEnum | NormalEnum`", () => {
|
it("should be equivalent to `TSNumericEnum | NormalEnum`", () => {
|
||||||
expectTypeOf<EnumOrObject>().branded.toEqualTypeOf<TSNumericEnum<EnumOrObject> | NormalEnum<EnumOrObject>>();
|
expectTypeOf<EnumOrObject>().toEqualTypeOf<TSNumericEnum<EnumOrObject> | NormalEnum<EnumOrObject>>();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -80,6 +92,7 @@ describe("Enum Functions", () => {
|
|||||||
describe("getEnumKeys", () => {
|
describe("getEnumKeys", () => {
|
||||||
it("should retrieve keys of numeric enum", () => {
|
it("should retrieve keys of numeric enum", () => {
|
||||||
expectTypeOf<typeof getEnumKeys<typeof testEnumNum>>().returns.toEqualTypeOf<("testN1" | "testN2")[]>();
|
expectTypeOf<typeof getEnumKeys<typeof testEnumNum>>().returns.toEqualTypeOf<("testN1" | "testN2")[]>();
|
||||||
|
expectTypeOf<typeof getEnumKeys<typeof testObjNum>>().returns.toEqualTypeOf<("testON1" | "testON2")[]>();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
"./system/*.ts"
|
"./system/*.ts"
|
||||||
],
|
],
|
||||||
"#trainers/*": ["./data/trainers/*.ts"],
|
"#trainers/*": ["./data/trainers/*.ts"],
|
||||||
"#types/*": ["./@types/*.ts", "./typings/phaser/*.ts"],
|
"#types/*": ["./@types/helpers/*.ts", "./@types/*.ts", "./typings/phaser/*.ts"],
|
||||||
"#ui/*": ["./ui/battle-info/*.ts", "./ui/settings/*.ts", "./ui/*.ts"],
|
"#ui/*": ["./ui/battle-info/*.ts", "./ui/settings/*.ts", "./ui/*.ts"],
|
||||||
"#utils/*": ["./utils/*.ts"],
|
"#utils/*": ["./utils/*.ts"],
|
||||||
"#data/*": ["./data/pokemon-forms/*.ts", "./data/pokemon/*.ts", "./data/*.ts"],
|
"#data/*": ["./data/pokemon-forms/*.ts", "./data/pokemon/*.ts", "./data/*.ts"],
|
||||||
|
Loading…
Reference in New Issue
Block a user