/** Matches any [primitive value](https://developer.mozilla.org/en-US/docs/Glossary/Primitive). @category Basic */ export type Primitive = null | undefined | string | number | boolean | symbol | bigint; /** Flatten the type output to improve type hints shown in editors. */ export type Simplify = { [KeyType in keyof T]: T[KeyType]; }; /** Returns a boolean for whether the two given types are equal. @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 */ export type IsEqual = (() => G extends T ? 1 : 2) extends () => G extends U ? 1 : 2 ? true : false; /** * Filter out keys from an object. * Returns `never` if `Exclude` is strictly equal to `Key`. * Returns `never` if `Key` extends `Exclude`. * Returns `Key` otherwise. */ type Filter = IsEqual extends true ? never : KeyType extends ExcludeType ? never : KeyType; /** Create a type from an object type without certain keys. 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. 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)). @example ``` import {Except} from 'type-fest'; type Foo = { a: number; b: string; c: boolean; }; type FooWithoutA = Except; //=> {b: string}; ``` @category Utilities */ export type Except = { [KeyType in keyof ObjectType as Filter]: ObjectType[KeyType]; }; /** Convert `object`s, `Map`s, `Set`s, and `Array`s and all of their keys/elements into immutable structures recursively. This is useful when a deeply nested structure needs to be exposed as completely immutable, for example, an imported JSON module or when receiving an API response that is passed around. Please upvote [this issue](https://github.com/microsoft/TypeScript/issues/13923) if you want to have this type as a built-in in TypeScript. @example ``` // data.json { "foo": ["bar"] } // main.ts import {ReadonlyDeep} from 'type-fest'; import dataJson = require('./data.json'); const data: ReadonlyDeep = dataJson; export default data; // test.ts import data from './main'; data.foo.push('bar'); //=> error TS2339: Property 'push' does not exist on type 'readonly string[]' ``` @category Utilities */ export type ReadonlyDeep = T extends Primitive | ((...args: any[]) => unknown) ? T : T extends ReadonlyMap ? ReadonlyMapDeep : T extends ReadonlySet ? ReadonlySetDeep : T extends object ? ReadonlyObjectDeep : unknown; /** Same as `ReadonlyDeep`, but accepts only `ReadonlyMap`s as inputs. Internal helper for `ReadonlyDeep`. */ interface ReadonlyMapDeep extends ReadonlyMap, ReadonlyDeep> { } /** Same as `ReadonlyDeep`, but accepts only `ReadonlySet`s as inputs. Internal helper for `ReadonlyDeep`. */ interface ReadonlySetDeep extends ReadonlySet> { } /** Same as `ReadonlyDeep`, but accepts only `object`s as inputs. Internal helper for `ReadonlyDeep`. */ type ReadonlyObjectDeep = { readonly [KeyType in keyof ObjectType]: ReadonlyDeep; }; /** * Pick only index signatures from the given object type, leaving out all explicitly defined properties. * This is the counterpart of `OmitIndexSignature`. * When you use a type that will iterate through an object that has indexed keys and explicitly defined keys you end up with a type where only the indexed keys are kept. This is because `keyof` of an indexed type always returns `string | number | symbol`, because every key is possible in that object. With this type, you can save the indexed keys and reinject them later, like in the second example below. */ export type PickIndexSignature = { [KeyType in keyof ObjectType as {} extends Record ? KeyType : never]: ObjectType[KeyType]; }; /** * Omit any index signatures from the given object type, leaving only explicitly defined properties. * This is the counterpart of `PickIndexSignature`. * Use-cases: * - Remove overly permissive signatures from third-party types. * * This type was taken from this [StackOverflow answer](https://stackoverflow.com/a/68261113/420747). * It relies on the fact that an empty object (`{}`) is assignable to an object with just an index signature, like `Record`, but not to an object with explicitly defined keys, like `Record<'foo' | 'bar', unknown>`. * (The actual value type, `unknown`, is irrelevant and could be any type. Only the key type matters.) */ export type OmitIndexSignature = { [KeyType in keyof ObjectType as {} extends Record ? never : KeyType]: ObjectType[KeyType]; }; /** Merge two types into a new type. Keys of the second type overrides keys of the first type. @example ``` import {Merge} from 'type-fest'; type Foo = { a: number; b: string; }; type Bar = { b: number; }; const ab: Merge = {a: 1, b: 2}; ``` @category Utilities */ export type Merge = { [Key in keyof OmitIndexSignature]: Key extends keyof Source ? Source[Key] : Key extends keyof Destination ? Destination[Key] : never; } & PickIndexSignature; /** Create a type that represents either the value or the value wrapped in `PromiseLike`. Use-cases: - A function accepts a callback that may either return a value synchronously or may return a promised value. - This type could be the return type of `Promise#then()`, `Promise#catch()`, and `Promise#finally()` callbacks. Please upvote [this issue](https://github.com/microsoft/TypeScript/issues/31394) if you want to have this type as a built-in in TypeScript. @example ``` import {Promisable} from 'type-fest'; async function logger(getLogEntry: () => Promisable): Promise { const entry = await getLogEntry(); console.log(entry); } logger(() => 'foo'); logger(() => Promise.resolve('bar')); @category Utilities ``` */ export type Promisable = T | PromiseLike; /** Extract the keys from a type where the value type of the key extends the given `Condition`. Internally this is used for the `ConditionalPick` and `ConditionalExcept` types. @example ``` import {ConditionalKeys} from 'type-fest'; interface Example { a: string; b: string | number; c?: string; d: {}; } type StringKeysOnly = ConditionalKeys; //=> 'a' ``` To support partial types, make sure your `Condition` is a union of undefined (for example, `string | undefined`) as demonstrated below. @example ``` type StringKeysAndUndefined = ConditionalKeys; //=> 'a' | 'c' ``` @category Utilities */ export type ConditionalKeys = NonNullable<{ [Key in keyof Base]: Base[Key] extends Condition ? Key : never; }[keyof Base]>; /** Exclude keys from a shape that matches the given `Condition`. This is useful when you want to create a new type with a specific set of keys from a shape. For example, you might want to exclude all the primitive properties from a class and form a new shape containing everything but the primitive properties. @example ``` import {Primitive, ConditionalExcept} from 'type-fest'; class Awesome { name: string; successes: number; failures: bigint; run() {} } type ExceptPrimitivesFromAwesome = ConditionalExcept; //=> {run: () => void} ``` @example ``` import {ConditionalExcept} from 'type-fest'; interface Example { a: string; b: string | number; c: () => void; d: {}; } type NonStringKeysOnly = ConditionalExcept; //=> {b: string | number; c: () => void; d: {}} ``` @category Utilities */ export type ConditionalExcept = Except>; /** Pick keys from the shape that matches the given `Condition`. This is useful when you want to create a new type from a specific subset of an existing type. For example, you might want to pick all the primitive properties from a class and form a new automatically derived type. @example ``` import {Primitive, ConditionalPick} from 'type-fest'; class Awesome { name: string; successes: number; failures: bigint; run() {} } type PickPrimitivesFromAwesome = ConditionalPick; //=> {name: string; successes: number; failures: bigint} ``` @example ``` import {ConditionalPick} from 'type-fest'; interface Example { a: string; b: string | number; c: () => void; d: {}; } type StringKeysOnly = ConditionalPick; //=> {a: string} ``` @category Utilities */ export type ConditionalPick = Pick>; /** Matches a [`class` constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes). @category Basic */ export type Class = new (...args: any[]) => T; /** Matches any [typed array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray), like `Uint8Array` or `Float64Array`. */ export type TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array | BigInt64Array | BigUint64Array; declare global { interface SymbolConstructor { readonly observable: symbol; } } /** Matches a value that is like an [Observable](https://github.com/tc39/proposal-observable). */ export interface ObservableLike { subscribe(observer: (value: unknown) => void): void; [Symbol.observable](): ObservableLike; } export {};