/** * When evaluating a very complex generic type alias, * tell TypeScript to use `T`, instead of current type alias' name, as the result type name * * Example: * * ```ts * type WithIdentity = Identity>; * type WithoutIdentity = SomeType; * * type WithIdentityResult = WithIdentity; * // Hover on this one shows `SomeType` * * type WithoutIdentityResult = WithoutIdentity; * // Hover on this one shows `WithoutIdentity` * ``` */ export type Identity = T; /** * Collapse an intersection type (`{ foo: string } & { bar: number }`) to a simple type (`{ foo: string, bar: number }`) */ export type Evaluate = T extends infer U ? { [K in keyof U]: U[K] } : never; /** * Overwrite fields in `TBase` with fields in `TNew` */ export type Overwrite = Evaluate< Omit & TNew >; /** * Remove fields with `never` type */ export type OmitNever = Pick< T, { [K in keyof T]: [T[K]] extends [never] ? never : K }[keyof T] >; /** * Extract keys of fields in `T` that has type `TValue` */ export type KeysOfType = { [TKey in keyof T]: T[TKey] extends TValue ? TKey : never; }[keyof T]; export type ValueOrPromise = T | PromiseLike; /** * Returns a (fake) value of the given type. */ export function placeholder(): T { return undefined as unknown as T; } // This library can't use `@types/node` or `lib: dom` // because they will pollute the global scope // So `TextEncoder` and `TextDecoder` types are not available // Node.js 8.3 ships `TextEncoder` and `TextDecoder` in `util` module. // But using top level await to load them requires Node.js 14.1. // So there is no point to do that. Let's just assume they exist in global. // eslint-disable-next-line @typescript-eslint/no-unused-vars declare class TextEncoderType { constructor(); encode(input: string): Uint8Array; } // eslint-disable-next-line @typescript-eslint/no-unused-vars declare class TextDecoderType { constructor(); decode(buffer: ArrayBufferView | ArrayBuffer): string; } interface GlobalExtension { TextEncoder: typeof TextEncoderType; TextDecoder: typeof TextDecoderType; } const { TextEncoder, TextDecoder } = globalThis as unknown as GlobalExtension; const SharedEncoder = /* #__PURE__ */ new TextEncoder(); const SharedDecoder = /* #__PURE__ */ new TextDecoder(); /* #__NO_SIDE_EFFECTS__ */ export function encodeUtf8(input: string): Uint8Array { return SharedEncoder.encode(input); } export function decodeUtf8(buffer: ArrayBufferView | ArrayBuffer): string { // `TextDecoder` has internal states in stream mode, // but this method is not for stream mode, so the instance can be reused return SharedDecoder.decode(buffer); }