@storm-stack/types
Version:
⚡ The storm-stack monorepo contains utility applications, tools, and various libraries to create modern and scalable web applications.
297 lines (294 loc) • 13.8 kB
TypeScript
import type { TypedArray } from "./array";
export type SerializablePrimitive = null | undefined | string | number | boolean | bigint;
export type Primitive = SerializablePrimitive | symbol;
/**
* Matches any primitive, `void`, `Date`, or `RegExp` value.
*/
export type BuiltIns = Primitive | void | Date | RegExp;
/**
* Matches any non-primitive object
*/
export type AtomicObject = Function | Promise<any> | Date | RegExp;
/** Determines if the passed value is of a specific type */
export type TypeTester = (value: any) => boolean;
/**
* The interface for a type mapping (key =\> function) to use for {@link getType}.
* export * The key represents the name of the type. The function represents the {@link TypeTester | test method}.
* The map should be ordered by testing preference, with more specific tests first.
* If a test returns true, it is selected, and the key is returned as the type.
*/
export type TypeMap = Record<string, TypeTester>;
declare const emptyObjectSymbol: unique symbol;
export type FunctionOrValue<Value> = Value extends () => infer X ? X : Value;
export type AnyFunction = (...args: any) => any;
export type Nullish = undefined | null;
export type Nullishable<T> = T | Nullish;
export type NonNullishObject = object;
export type NativeClass = abstract new (...args: any) => any;
export type AnyNumber = number | number;
export type AnyString = string | string;
export type AnyBoolean = boolean | boolean;
export type AnyArray = any[];
export type PlainObject = Record<any, object>;
export type AnyMap = Map<any, any>;
export type AnyWeakMap = WeakMap<WeakKey, any>;
export type EmptyArray = [];
export interface EmptyObject {
[emptyObjectSymbol]?: never;
}
export type Any = boolean | number | bigint | string | null | undefined | void | symbol | object | PlainObject | AnyArray | AnyMap | AnyWeakMap;
/**
* The valid types of the index for an `Indexable` type object
*/
export type IndexType = string | number | symbol;
/**
* The declaration of a ***dictionary-type*** object
*/
export type Indexable = Record<IndexType, any>;
export declare const EMPTY_STRING = "";
export declare const NEWLINE_STRING = "\r\n";
export declare const EMPTY_OBJECT: {};
export type AnyCase<T extends IndexType> = string extends T ? string : T extends `${infer F1}${infer F2}${infer R}` ? `${Uppercase<F1> | Lowercase<F1>}${Uppercase<F2> | Lowercase<F2>}${AnyCase<R>}` : T extends `${infer F}${infer R}` ? `${Uppercase<F> | Lowercase<F>}${AnyCase<R>}` : typeof EMPTY_STRING;
export type Newable<T> = new (..._args: never[]) => T;
export interface Abstract<T> {
prototype: T;
}
export interface Clonable<T> {
clone(): T;
}
export type MaybePromise<T> = T | Promise<T>;
export type ReducerFunction<TState, TAction> = (state: TState, action: TAction) => TState;
export declare const TYPE_ARGUMENTS = "Arguments";
export declare const TYPE_ARRAY = "Array";
export declare const TYPE_OBJECT = "Object";
export declare const TYPE_MAP = "Map";
export declare const TYPE_SET = "Set";
export type Collection = IArguments | unknown[] | Map<unknown, unknown> | Record<string | number | symbol, unknown> | Set<unknown>;
export type NonUndefined<T> = T extends undefined ? never : T;
export type BrowserNativeObject = Date | File;
export type DeepPartial<T> = T extends BrowserNativeObject | NestedValue ? T : {
[K in keyof T]?: DeepPartial<T[K]>;
};
export type Rollback = Record<string, (initialValue: any, currentValue: any) => any>;
/**
* Extract all required keys from the given type.
*
* @remarks This is useful when you want to create a new type that contains different type values for the required keys only or use the list of keys for validation purposes, etc...
* @category Utilities
*/
export type RequiredKeysOf<BaseType extends object> = Exclude<{
[Key in keyof BaseType]: BaseType extends Record<Key, BaseType[Key]> ? Key : never;
}[keyof BaseType], undefined>;
/**
* Returns a boolean for whether the two given types are equal.
*
* @remarks Use-cases: If you want to make a conditional branch based on the result of a comparison of two types.
* @link https://github.com/microsoft/TypeScript/issues/27024#issuecomment-421529650
* @link https://stackoverflow.com/questions/68961864/how-does-the-equals-work-in-typescript/68963796#68963796
* @category Type Guard
* @category Utilities
*/
export type IsEqual<A, B> = (<G>() => G extends A ? 1 : 2) extends <G>() => G extends B ? 1 : 2 ? true : false;
export type Filter<KeyType, ExcludeType> = IsEqual<KeyType, ExcludeType> extends true ? never : KeyType extends ExcludeType ? never : KeyType;
interface ExceptOptions {
/**
Disallow assigning non-specified properties.
Note that any omitted properties in the resulting type will be present in autocomplete as `undefined`.
@defaultValue false
*/
requireExactProps?: boolean;
}
/**
* Create a type from an object type without certain keys.
*
* @remarks We recommend setting the `requireExactProps` option to `true`.
* @remarks This type is a stricter version of [`Omit`](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-5.html#the-omit-helper-type). The `Omit` type does not restrict the omitted keys to be keys present on the given type, while `Except` does. The benefits of a stricter type are avoiding typos and allowing the compiler to pick up on rename refactors automatically.
* @remarks This type was proposed to the TypeScript team, which declined it, saying they prefer that libraries implement stricter versions of the built-in types ([microsoft/TypeScript#30825](https://github.com/microsoft/TypeScript/issues/30825#issuecomment-523668235)).
* @category Object
*/
export type Except<ObjectType, KeysType extends keyof ObjectType, Options extends ExceptOptions = {
requireExactProps: false;
}> = {
[KeyType in keyof ObjectType as Filter<KeyType, KeysType>]: ObjectType[KeyType];
} & (Options["requireExactProps"] extends true ? Partial<Record<KeysType, never>> : Record<string, never>);
/**
* Useful to flatten the type output to improve type hints shown in editors. And also to transform an interface into a type to aide with assignability.
*
* @remarks Sometimes it is desired to pass a value as a function argument that has a different type. At first inspection it may seem assignable, and then you discover it is not because the `value`'s type definition was defined as an interface. In the following example, `fn` requires an argument of type `Record<string, unknown>`. If the value is defined as a literal, then it is assignable. And if the `value` is defined as type using the `Simplify` utility the value is assignable. But if the `value` is defined as an interface, it is not assignable because the interface is not sealed and elsewhere a non-string property could be added to the interface.
* @remarks If the type definition must be an interface (perhaps it was defined in a third-party npm package), then the `value` can be defined as `const value: Simplify<SomeInterface> = ...`. Then `value` will be assignable to the `fn` argument. Or the `value` can be cast as `Simplify<SomeInterface>` if you can't re-declare the `value`.
* @link https://github.com/microsoft/TypeScript/issues/15300
* @category Object
*/
export type Simplify<T> = {
[KeyType in keyof T]: T[KeyType];
} & {};
/**
* Create a type that makes the given keys required. The remaining keys are kept as is. The sister of the `SetOptional` type.
*
* @remarks Use-case: You want to define a single model where the only thing that changes is whether or not some of the keys are required.
* @category Object
*/
export type SetRequired<BaseType, Keys extends keyof BaseType> = BaseType extends unknown ? Simplify<Except<BaseType, Keys> & Required<Pick<BaseType, Keys>>> : never;
export declare const $NestedValue: unique symbol;
export type NestedValue<TValue extends object = object> = {
[$NestedValue]: never;
} & TValue;
export interface RefObject<T> {
current: T;
}
export interface IIdentity<T = string> {
id: T;
}
export interface IVersioned {
version: number;
}
export interface ISequenced {
/**
* The sequence number (version, or event counter, etc.) of the record
*/
sequence: number;
}
export interface ITyped {
/**
* The type of the record
*/
__typename: string;
}
export interface ClassTypeCheckable<T> extends ITyped {
/**
* Run type check on the given value
* @param value - The value to check
* @returns True if the value is of the type of the class
*/
isTypeOf: (value: unknown) => value is T;
}
/**
* Matches non-recursive types.
*/
export type NonRecursiveType = BuiltIns | Function | (new (...arguments_: any[]) => unknown);
export type IsPrimitive<T> = [T] extends [Primitive] ? true : false;
export type IsNever<T> = [T] extends [never] ? true : false;
export type IsAny<T> = 0 extends 1 & T ? true : false;
export type IsNull<T> = [T] extends [null] ? true : false;
export type IsUndefined<T> = T extends undefined ? true : false;
export type IsUnknown<T> = unknown extends T ? IsNull<T> extends false ? true : false : false;
export type IsNullish<T> = IsNull<T> & IsUndefined<T>;
export type IsFunction<T> = T extends AnyFunction ? true : false;
/**
* Declare locally scoped properties on `globalThis`.
*
* When defining a global variable in a declaration file is inappropriate, it can be helpful to define a `type` or `interface` (say `ExtraGlobals`) with the global variable and then cast `globalThis` via code like `globalThis as unknown as ExtraGlobals`.
*
* Instead of casting through `unknown`, you can update your `type` or `interface` to extend `GlobalThis` and then directly cast `globalThis`.
*
* @example
* ```
* import type {GlobalThis} from 'type-fest';
*
* type ExtraGlobals = GlobalThis & {
* readonly GLOBAL_TOKEN: string;
* };
*
* (globalThis as ExtraGlobals).GLOBAL_TOKEN;
* ```
*
* @category Type
*/
export type GlobalThis = typeof globalThis;
/**
* Matches a [`class`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes).
*
* @category Class
*/
export interface Class<T, Arguments extends unknown[] = any[]> {
prototype: Pick<T, keyof T>;
new (...arguments_: Arguments): T;
}
/**
* Matches a [`class` constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes).
*
* @category Class
*/
export type Constructor<T, Arguments extends unknown[] = any[]> = new (...arguments_: Arguments) => T;
/**
* Matches an [`abstract class`](https://www.typescriptlang.org/docs/handbook/classes.html#abstract-classes).
*
* @category Class
*
* @privateRemarks
* We cannot use a `type` here because TypeScript throws: 'abstract' modifier cannot appear on a type member. (1070)
*/
export interface AbstractClass<T, Arguments extends unknown[] = any[]> extends AbstractConstructor<T, Arguments> {
prototype: Pick<T, keyof T>;
}
/**
* Matches an [`abstract class`](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-2.html#abstract-construct-signatures) constructor.
*
* @category Class
*/
export type AbstractConstructor<T, Arguments extends unknown[] = any[]> = abstract new (...arguments_: Arguments) => T;
/**
* Create a tuple type of the given length `<L>` and fill it with the given type `<Fill>`.
*
* If `<Fill>` is not provided, it will default to `unknown`.
*
* @link https://itnext.io/implementing-arithmetic-within-typescripts-type-system-a1ef140a6f6f
*/
export type BuildTuple<L extends number, Fill = unknown, T extends readonly unknown[] = []> = T["length"] extends L ? T : BuildTuple<L, Fill, [...T, Fill]>;
/**
* Test if the given function has multiple call signatures.
*
* Needed to handle the case of a single call signature with properties.
*
* Multiple call signatures cannot currently be supported due to a TypeScript limitation.
* @see https://github.com/microsoft/TypeScript/issues/29732
*/
export type HasMultipleCallSignatures<T extends (...arguments_: any[]) => unknown> = T extends {
(...arguments_: infer A): unknown;
(...arguments_: infer B): unknown;
} ? B extends A ? A extends B ? false : true : true : false;
type StructuredCloneablePrimitive = string | number | bigint | boolean | null | undefined | boolean | number | string;
type StructuredCloneableData = ArrayBuffer | DataView | Date | Error | RegExp | TypedArray | Blob | File;
type StructuredCloneableCollection = readonly StructuredCloneable[] | {
readonly [key: string]: StructuredCloneable;
readonly [key: number]: StructuredCloneable;
} | ReadonlyMap<StructuredCloneable, StructuredCloneable> | ReadonlySet<StructuredCloneable>;
/**
* Matches a value that can be losslessly cloned using `structuredClone`.
*
* Note:
* - Custom error types will be cloned as the base `Error` type
* - This type doesn't include types exclusive to the TypeScript DOM library (e.g. `DOMRect` and `VideoFrame`)
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm
*
* @example
* ```
* import type {StructuredCloneable} from 'type-fest';
*
* class CustomClass {}
*
* // @ts-expect-error
* const error: StructuredCloneable = {
* custom: new CustomClass(),
* };
*
* structuredClone(error);
* //=> {custom: {}}
*
* const good: StructuredCloneable = {
* number: 3,
* date: new Date(),
* map: new Map<string, number>(),
* }
*
* good.map.set('key', 1);
*
* structuredClone(good);
* //=> {number: 3, date: Date(2022-10-17 22:22:35.920), map: Map {'key' -> 1}}
* ```
*
* @category Structured clone
*/
export type StructuredCloneable = StructuredCloneablePrimitive | StructuredCloneableData | StructuredCloneableCollection;
export {};