UNPKG

@web5/common

Version:
206 lines 8.67 kB
/** * Represents an array of a fixed length, preventing modifications to its size. * * The `FixedLengthArray` utility type transforms a standard array into a variant where * methods that could alter the length are omitted. It leverages TypeScript's advanced types, * such as conditional types and mapped types, to ensure that the array cannot be resized * through methods like `push`, `pop`, `splice`, `shift`, and `unshift`. The utility type * maintains all other characteristics of a standard array, including indexing, iteration, * and type checking for its elements. * * Note: The type does not prevent direct assignment to indices, even if it would exceed * the original length. However, such actions would lead to TypeScript type errors. * * @example * ```ts * // Declare a variable with a type of fixed-length array of three strings. * let myFixedLengthArray: FixedLengthArray< [string, string, string]>; * * // Array declaration tests * myFixedLengthArray = [ 'a', 'b', 'c' ]; // OK * myFixedLengthArray = [ 'a', 'b', 123 ]; // TYPE ERROR * myFixedLengthArray = [ 'a' ]; // LENGTH ERROR * myFixedLengthArray = [ 'a', 'b' ]; // LENGTH ERROR * * // Index assignment tests * myFixedLengthArray[1] = 'foo'; // OK * myFixedLengthArray[1000] = 'foo'; // INVALID INDEX ERROR * * // Methods that mutate array length * myFixedLengthArray.push('foo'); // MISSING METHOD ERROR * myFixedLengthArray.pop(); // MISSING METHOD ERROR * * // Direct length manipulation * myFixedLengthArray.length = 123; // READ-ONLY ERROR * * // Destructuring * let [ a ] = myFixedLengthArray; // OK * let [ a, b ] = myFixedLengthArray; // OK * let [ a, b, c ] = myFixedLengthArray; // OK * let [ a, b, c, d ] = myFixedLengthArray; // INVALID INDEX ERROR * ``` * * @template T extends any[] - The array type to be transformed. */ export type FixedLengthArray<T extends any[]> = Pick<T, Exclude<keyof T, ArrayLengthMutationKeys>> & { /** * Custom iterator for the `FixedLengthArray` type. * * This iterator allows the `FixedLengthArray` to be used in standard iteration * contexts, such as `for...of` loops and spread syntax. It ensures that even though * the array is of a fixed length with disabled mutation methods, it still retains * iterable behavior similar to a regular array. * * @returns An IterableIterator for the array items. */ [Symbol.iterator]: () => IterableIterator<ArrayItems<T>>; }; /** Helper types for {@link FixedLengthArray} */ type ArrayLengthMutationKeys = 'splice' | 'push' | 'pop' | 'shift' | 'unshift' | number; type ArrayItems<T extends Array<any>> = T extends Array<infer TItems> ? TItems : never; /** * isArrayBufferSlice * * Checks if the ArrayBufferView represents a slice (subarray or a subview) * of an ArrayBuffer. * * An ArrayBufferView (TypedArray or DataView) can represent a portion of an * ArrayBuffer - such a view is said to be a "slice" of the original buffer. * This can occur when the `subarray` or `slice` method is called on a * TypedArray or when a DataView is created with a byteOffset and/or * byteLength that doesn't cover the full ArrayBuffer. * * @param arrayBufferView - The ArrayBufferView to be checked * @returns true if the ArrayBufferView represents a slice of an ArrayBuffer; false otherwise. */ export declare function isArrayBufferSlice(arrayBufferView: ArrayBufferView): boolean; /** * Checks if the given object is an AsyncIterable. * * An AsyncIterable is an object that implements the AsyncIterable protocol, * which means it has a [Symbol.asyncIterator] method. This function checks * if the provided object conforms to this protocol by verifying the presence * and type of the [Symbol.asyncIterator] method. * * @param obj - The object to be checked for AsyncIterable conformity. * @returns True if the object is an AsyncIterable, false otherwise. * * @example * ```ts * // Returns true for a valid AsyncIterable * const asyncIterable = { * async *[Symbol.asyncIterator]() { * yield 1; * yield 2; * } * }; * console.log(isAsyncIterable(asyncIterable)); // true * ``` * * @example * ```ts * // Returns false for a regular object * console.log(isAsyncIterable({ a: 1, b: 2 })); // false * ``` */ export declare function isAsyncIterable(obj: any): obj is AsyncIterable<any>; /** * isDefined * * Utility function to check if a variable is neither null nor undefined. * This function helps in making TypeScript infer the type of the variable * as being defined, excluding `null` and `undefined`. * * The function uses strict equality (`!==`) for the comparison, ensuring * that the variable is not just falsy (like an empty string or zero), * but is truly either `null` or `undefined`. * * @param arg - The variable to be checked * @returns true if the variable is neither `null` nor `undefined` */ export declare function isDefined<T>(arg: T): arg is Exclude<T, null | undefined>; /** * Utility type that transforms a type `T` to have only certain keys `K` as required, while the * rest remain optional, except for keys specified in `O`, which are omitted entirely. * * This type is useful when you need a variation of a type where only specific properties are * required, and others are either optional or not included at all. It allows for more flexible type * definitions based on existing types without the need to redefine them. * * @template T - The original type to be transformed. * @template K - The keys of `T` that should be required. * @template O - The keys of `T` that should be omitted from the resulting type (optional). * * @example * ```ts * // Given an interface * interface Example { * requiredProp: string; * optionalProp?: number; * anotherOptionalProp?: boolean; * } * * // Making 'optionalProp' required and omitting 'anotherOptionalProp' * type ModifiedExample = RequireOnly<Example, 'optionalProp', 'anotherOptionalProp'>; * // Result: { requiredProp?: string; optionalProp: number; } * ``` */ export type RequireOnly<T, K extends keyof T, O extends keyof T = never> = Required<Pick<T, K>> & Omit<Partial<T>, O>; /** * universalTypeOf * * Why does this function exist? * * You can typically check if a value is of a particular type, such as * Uint8Array or ArrayBuffer, by using the `instanceof` operator. The * `instanceof` operator checks the prototype property of a constructor * in the object's prototype chain. * * However, there is a caveat with the `instanceof` check if the value * was created from a different JavaScript context (like an iframe or * a web worker). In those cases, the `instanceof` check might fail * because each context has a different global object, and therefore, * different built-in constructor functions. * * The `typeof` operator provides information about the type of the * operand in a less detailed way. For basic data types like number, * string, boolean, and undefined, the `typeof` operator works as * expected. However, for objects, including arrays and null, * it always returns "object". For functions, it returns "function". * So, while `typeof` is good for basic type checking, it doesn't * give detailed information about complex data types. * * Unlike `instanceof` and `typeof`, `Object.prototype.toString.call(value)` * can ensure a consistent result across different JavaScript * contexts. * * Credit for inspiration: * Angus Croll * https://github.com/angus-c * https://javascriptweblog.wordpress.com/2011/08/08/fixing-the-javascript-typeof-operator/ */ export declare function universalTypeOf(value: unknown): string; /** * Utility type to extract the type resolved by a Promise. * * This type unwraps the type `T` from `Promise<T>` if `T` is a Promise, otherwise returns `T` as * is. It's useful in situations where you need to handle the type returned by a promise-based * function in a synchronous context, such as defining types for test vectors or handling return * types in non-async code blocks. * * @template T - The type to unwrap from the Promise. * * @example * ```ts * // For a Promise type, it extracts the resolved type. * type AsyncNumber = Promise<number>; * type UnwrappedNumber = UnwrapPromise<AsyncNumber>; // number * * // For a non-Promise type, it returns the type as is. * type StringValue = string; * type UnwrappedString = UnwrapPromise<StringValue>; // string * ``` */ export type UnwrapPromise<T> = T extends Promise<infer U> ? U : T; export {}; //# sourceMappingURL=type-utils.d.ts.map