/* * A collection of custom utility types that aid in type checking and ensuring strict type conformity */ import type { AbAttr } from "#abilities/ability"; /** * Exactly matches the type of the argument, preventing adding additional properties. * * ⚠️ Should never be used with `extends`, as this will nullify the exactness of the type. * * As an example, used to ensure that the parameters of {@linkcode AbAttr.canApply} and {@linkcode AbAttr.getTriggerMessage} * are compatible with the type of its {@linkcode AbAttr.apply | apply} method. * * @typeParam T - The type to match exactly */ export type Exact = { [K in keyof T]: T[K]; }; /** * Type hint that indicates that the type is intended to be closed to a specific shape. * Does not actually do anything special, is really just an alias for X. */ export type Closed = X; /** * Helper type to strip `readonly` from all properties of the provided type. * Inverse of {@linkcode Readonly} * @typeParam T - The type to make mutable */ export type Mutable = { -readonly [P in keyof T]: T[P]; }; /** * Type helper to obtain the keys associated with a given value inside an object. \ * Functions similarly to `Pick`, but checking assignability of values instead of keys. * @typeParam O - The type of the object * @typeParam V - The type of one of O's values. */ export type InferKeys = { [K in keyof O]: O[K] extends V ? K : never; }[keyof O]; /** * Utility type to obtain a union of the values of a given object. \ * Functions similar to `keyof E`, except producing the values instead of the keys. * @typeParam E - The type of the object * @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[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; /** * Type helper to extract non-function properties from a type. * * @remarks * Useful to produce a type that is roughly the same as the type of `{... obj}`, where `obj` is an instance of `T`. * A couple of differences: * - Private and protected properties are not included. * - Nested properties are not recursively extracted. For this, use {@linkcode NonFunctionPropertiesRecursive} */ export type NonFunctionProperties = { [K in keyof T as T[K] extends AnyFn ? never : K]: T[K]; }; /** * 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 = { [K in keyof Class as Class[K] extends AnyFn ? never : K]: Class[K] extends Array ? NonFunctionPropertiesRecursive[] : Class[K] extends object ? NonFunctionPropertiesRecursive : Class[K]; }; /** Utility type for an abstract constructor. */ export type AbstractConstructor = abstract new (...args: any[]) => T; /** * Type helper that iterates through the fields of the type and coerces any `null` properties to `undefined` (including in union types). * * @remarks * This is primarily useful when an object with nullable properties wants to be serialized and have its `null` * properties coerced to `undefined`. */ export type CoerceNullPropertiesToUndefined = { [K in keyof T]: null extends T[K] ? Exclude | undefined : T[K]; }; /** * Type helper to mark all properties in `T` as optional, while still mandating that at least 1 * of its properties be present. * * Distinct from {@linkcode Partial} as this requires at least 1 property to _not_ be undefined. * @typeParam T - The object type to render partial */ export type AtLeastOne = Partial & ObjectValues<{ [K in keyof T]: Pick, K> }>; /** * Type helper that adds a brand to a type, used for nominal typing. * * @remarks * Brands should be either a string or unique symbol. This prevents overlap with other types. */ export declare class Brander { private __brand: B; }