UNPKG

helpertypes

Version:

A collection of TypeScript helper types

398 lines 13.1 kB
/** * Makes T a union of T, null, and undefined */ export declare type Nullable<T> = T | null | undefined; /** * Makes all properties of T mutable */ export declare type Mutable<T> = { -readonly [P in keyof T]: T[P]; }; /** * Picks the element type of the given iterable. * For example, for the given array literal type: ["foo", "bar", "baz"], * the type is "foo"|"bar"|"baz" */ export declare type ElementOf<Iterable> = Iterable extends (infer ArrayElementType)[] ? ArrayElementType : Iterable extends readonly (infer ReadonlyArrayElementType)[] ? ReadonlyArrayElementType : Iterable extends Set<infer SetElementType> ? SetElementType : Iterable extends string ? Iterable : never; /** * Something that is an array of T's or a single T */ export declare type MaybeArray<T> = T[] | T; /** * Ensures that T is an array of the element type of T */ export declare type EnsureArray<T> = T extends (infer U)[] ? U[] : T[]; /** * A variant of Required where not only the keys are required, but also the values */ export declare type RequiredValues<T> = { [P in keyof T]-?: Exclude<T[P], null | undefined>; }; /** * Picks only keys for which there is an optional modifier */ export declare type PickOptional<T> = Pick<T, Exclude<{ [K in keyof T]: T extends Record<K, T[K]> ? never : K; }[keyof T], undefined>>; /** * Picks only keys for which there is no optional modifier */ export declare type PickRequired<T> = Pick<T, Exclude<{ [K in keyof T]: T extends Record<K, T[K]> ? K : never; }[keyof T], undefined>>; /** * Picks those keys from A that intersects with those from B */ export declare type PickIntersectingKeys<A, B> = Pick<A, Exclude<{ [Key in keyof A]: Key extends keyof B ? Key : never; }[keyof A], undefined>>; /** * Picks from T the properties for which their type matches Type */ export declare type PickMembersOfType<T, Type> = Pick<T, { [Key in keyof T]: T[Key] extends Type ? Key : never; }[keyof T]>; export declare type PickMembersOfNotOfType<T, Type> = Pick<T, { [Key in keyof T]: T[Key] extends Type ? never : T[Key] extends Type | undefined ? never : Key; }[keyof T]>; /** * Builds up a lookup path into a record via tuple elements. For example, for the record `{ a: {b: {c: string}}}`, a valid value could be `["a", "b", "c"]` * It takes as the second optional type argument the maximum depth it can recursively descent into the target object (default: 10). * When an Array is discovered, indexes into the array can be provided. For example, for the record `{a: {foo: string}[]}`, a value like `["a", 0, "foo"]` is allowed. */ export declare type ObjectLookupTuple<T, MaxDepth extends number = 10> = ObjectLookupTupleHelper<T, [], MaxDepth>; declare type ObjectLookupTupleHelper<T, Acc extends PropertyKey[], MaxDepth extends number, CurrentDepth extends number = 0> = { [Key in keyof T]: CurrentDepth extends MaxDepth ? [...Acc, Key] : T[Key] extends IgnoredLookupValue ? [...Acc, Key] : T[Key] extends (infer El)[] | readonly (infer El)[] ? [...Acc, Key] | ObjectLookupTupleHelper<El, [...Acc, Key, number], MaxDepth, Next<CurrentDepth>> : [...Acc, Key] | ObjectLookupTupleHelper<NonNullable<T[Key]>, [...Acc, Key, number], MaxDepth, Next<CurrentDepth>>; }[keyof T]; /** * A variant of ObjectLookupTuple that will walk into arrays and allow looking up members of their records as part of the lookup path. For * example, for the record `{a: {foo: string}[]}`, a value like `["a", "foo"]` is allowed, even though 'foo' is part of a record within an array */ export declare type ArrayPiercingObjectLookupTuple<T, MaxDepth extends number = 10> = ArrayPiercingObjectLookupTupleHelper<T, [], MaxDepth>; declare type ArrayPiercingObjectLookupTupleHelper<T, Acc extends PropertyKey[], MaxDepth extends number, CurrentDepth extends number = 0> = { [Key in keyof T]: CurrentDepth extends MaxDepth ? [...Acc, Key] : T[Key] extends IgnoredLookupValue ? [...Acc, Key] : T[Key] extends (infer El)[] | readonly (infer El)[] ? [...Acc, Key] | ArrayPiercingObjectLookupTupleHelper<El, [...Acc, Key], MaxDepth, Next<CurrentDepth>> : [...Acc, Key] | ArrayPiercingObjectLookupTupleHelper<NonNullable<T[Key]>, [...Acc, Key], MaxDepth, Next<CurrentDepth>>; }[keyof T]; /** * Behaves similar to ObjectLookupTuple, but builds up strings that dot into objects. For example, for the record `{ a: {b: {c: string}}}`, a valid value could be `a.b.c` */ export declare type ObjectLookupString<T, MaxDepth extends number = 10, StopAtArrays extends boolean = false> = ObjectLookupStringHelper<T, ``, MaxDepth, 0, StopAtArrays>; declare type MaybeSuffixWithDot<T extends string> = T extends `` ? T : `${T}.`; declare type ObjectLookupStringHelper<T, Acc extends string, MaxDepth extends number, CurrentDepth extends number = 0, StopAtArrays extends boolean = false> = { [Key in keyof T]: Key extends string ? CurrentDepth extends MaxDepth ? `${MaybeSuffixWithDot<Acc>}${Key}` : T[Key] extends IgnoredLookupValue ? `${MaybeSuffixWithDot<Acc>}${Key}` : T[Key] extends (infer El)[] | readonly (infer El)[] ? StopAtArrays extends true ? `${MaybeSuffixWithDot<Acc>}${Key}` : `${MaybeSuffixWithDot<Acc>}${Key}.${number}` | El extends IgnoredLookupValue ? `${MaybeSuffixWithDot<Acc>}${Key}.${number}` : ObjectLookupStringHelper<El, `${MaybeSuffixWithDot<Acc>}${Key}.${number}`, MaxDepth, Next<CurrentDepth>, StopAtArrays> : `${MaybeSuffixWithDot<Acc>}${Key}` | ObjectLookupStringHelper<NonNullable<T[Key]>, `${MaybeSuffixWithDot<Acc>}${Key}`, MaxDepth, Next<CurrentDepth>, StopAtArrays> : never; }[keyof T]; /** * A variant of Partial that is deep. * This means that every value is a partial recursively * while still preserving primitive or built-in types as they are */ export declare type PartialDeep<T, MaxDepth extends number = 10, CurrentDepth extends number = 0> = CurrentDepth extends MaxDepth ? T : T extends IgnoredLookupValue ? T : T extends (infer ArrayElement)[] ? PartialDeep<ArrayElement, MaxDepth, Next<CurrentDepth>>[] : T extends readonly (infer ReadonlyArrayElement)[] ? readonly PartialDeep<ReadonlyArrayElement, MaxDepth, Next<CurrentDepth>>[] : T extends Iterable<infer IterableType> ? Iterable<PartialDeep<IterableType, MaxDepth, Next<CurrentDepth>>> : { [P in keyof T]?: PartialDeep<T[P], MaxDepth, Next<CurrentDepth>>; }; /** * A variant of Required that is deep. * This means that every key is required recursively * while still preserving primitive or built-in types as they are */ export declare type RequiredDeep<T, MaxDepth extends number = 10, CurrentDepth extends number = 0> = CurrentDepth extends MaxDepth ? T : T extends IgnoredLookupValue ? T : T extends (infer ArrayElement)[] ? RequiredDeep<ArrayElement, MaxDepth, Next<CurrentDepth>>[] : T extends readonly (infer ReadonlyArrayElement)[] ? readonly RequiredDeep<ReadonlyArrayElement, MaxDepth, Next<CurrentDepth>>[] : T extends Iterable<infer IterableType> ? Iterable<RequiredDeep<IterableType, MaxDepth, Next<CurrentDepth>>> : { [P in keyof T]-?: RequiredDeep<T[P], MaxDepth, Next<CurrentDepth>>; }; /** * A partial of T except for the keys given in K */ export declare type PartialExcept<T, K extends keyof T> = Omit<Partial<T>, K> & Pick<T, K>; /** * A partial of T except for the keys given in K */ export declare type PartialDeepExcept<T, K extends keyof T> = Omit<PartialDeep<T>, K> & Pick<T, K>; /** * Require all keys in T, except for the keys given in K */ export declare type RequiredExcept<T, K extends keyof T> = Omit<Required<T>, K> & Pick<T, K>; /** * Splits a record into all of its possible property intersections. * For example, for the record {a: 1; b: 2>}, splitting the record will * get the type {a: 1} | {b: 2} back. */ export declare type SplitRecord<T, U = T> = Exclude<{ [Key in keyof T]: { [K in Key]: K extends keyof U ? T[K] : never; }; }[keyof T], undefined>; /** * A variant of `SplitRecord` that includes all similar keys. * See the documentation for `SimilarObjectKeys` for more details. */ export declare type SplitRecordWithSimilarKeys<T, U = T> = Exclude<{ [Key in keyof T]: Key extends keyof U ? SimilarObjectKeys<T, Key & string> : never; }[keyof T], undefined>; /** * Selects only the properties from an object for which the keys include the substring(s) given in U. * For example, for the object {foo: 1, fooBar: 2, barFoo: 3, baz: 4}, a value of "foo" for U will return an object with only the keys "foo", "fooBar", and "barFoo" */ export declare type SimilarObjectKeys<T, U extends keyof T & string> = PickMembersOfNotOfType<{ [TKey in keyof T]: TKey extends U ? T[TKey] : TKey extends `${infer _Prefix}${Capitalize<U>}` ? T[TKey] | undefined : TKey extends `${infer _Prefix}${U}` ? T[TKey] | undefined : TKey extends `${U}${infer _Suffix}` ? T[TKey] | undefined : never; }, never>; /** * An arbitrary Function that takes any amount of arguments and returns anything */ export declare type ArbitraryFunction<ReturnType = unknown> = (...args: never[]) => ReturnType; export declare type ArbitraryConstructor<T> = new (...args: never[]) => T; /** * Gets the length of T */ export declare type GetLength<T extends unknown[]> = T extends { length: infer L; } ? L : never; /** * Gets the first element of T */ export declare type GetFirst<T extends unknown[]> = T[0]; /** * Gets the last element of T */ export declare type GetLast<T extends unknown[]> = T[Prev<GetLength<T>>]; /** * Gets the Nth parameter of the given function */ export declare type NthParameter<T extends ArbitraryFunction, Parameter extends number> = Parameters<T>[Parameter]; /** * Gets the first parameter of the given function */ export declare type FirstParameter<T extends ArbitraryFunction> = GetFirst<Parameters<T>>; /** * Gets the last parameter of the given function */ export declare type LastParameter<T extends ArbitraryFunction> = GetLast<Parameters<T>>; export declare type UncapitalizeKeys<T> = { [Key in keyof T as Uncapitalize<string & Key>]: T[Key]; }; export declare type CapitalizeKeys<T> = { [Key in keyof T as Capitalize<string & Key>]: T[Key]; }; export declare type LowercaseKeys<T> = { [Key in keyof T as Lowercase<string & Key>]: T[Key]; }; export declare type UppercaseKeys<T> = { [Key in keyof T as Uppercase<string & Key>]: T[Key]; }; export declare type PrefixObjectKeys<T, Prefix extends string, EnsureCamelCase = false> = { [Key in keyof T as SuffixKey<Key & string, Prefix, EnsureCamelCase>]: T[Key]; }; export declare type SuffixObjectKeys<T, Suffix extends string, EnsureCamelCase = false> = { [Key in keyof T as PrefixKey<Key & string, Suffix, EnsureCamelCase>]: T[Key]; }; export declare type PrefixKey<T extends string, Prefix extends string, EnsureCamelCase = false> = `${Prefix}${EnsureCamelCase extends true ? Capitalize<T> : T}`; export declare type SuffixKey<T extends string, Suffix extends string, EnsureCamelCase = false> = `${T}${EnsureCamelCase extends true ? Capitalize<Suffix> : Suffix}`; export declare type Prev<T extends number> = [ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100 ][T]; export declare type Next<T extends number> = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101 ][T]; /** * A type indicating something that shouldn't be traversed into when mapping over objects, lists, or other similar data structures */ export declare type IgnoredLookupValue = string | number | bigint | symbol | boolean | undefined | null | Date | RegExp | CallableFunction | Set<unknown> | WeakSet<never> | Map<unknown, unknown> | WeakMap<never, unknown>; export {}; //# sourceMappingURL=index.d.ts.map