UNPKG

type-fest

Version:

A collection of essential TypeScript types

64 lines (48 loc) 1.81 kB
import type {ExtendsStrict} from './extends-strict.d.ts'; import type {IfNotAnyOrNever} from './internal/type.d.ts'; import type {TupleToObject} from './tuple-to-object.d.ts'; import type {UnknownArray} from './unknown-array.d.ts'; /** 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 type {ConditionalKeys} from 'type-fest'; type Example = { a: string; b: string | number; c?: string; d: {}; }; type StringKeysOnly = ConditionalKeys<Example, string>; //=> 'a' ``` Note: To extract optional keys, make sure your `Condition` is a union of `undefined` (for example, `string | undefined`) as demonstrated below. @example ``` import type {ConditionalKeys} from 'type-fest'; type StringKeysAndUndefined = ConditionalKeys<{a?: string}, string | undefined>; //=> 'a' type NoMatchingKeys = ConditionalKeys<{a?: string}, string>; //=> never ``` You can also extract array indices whose value match the specified condition, as shown below: ``` import type {ConditionalKeys} from 'type-fest'; type StringValueIndices = ConditionalKeys<[string, number, string], string>; //=> '0' | '2' type NumberValueIndices = ConditionalKeys<[string, number?, string?], number | undefined>; //=> '1' ``` @category Object */ export type ConditionalKeys<Base, Condition> = (Base extends UnknownArray ? TupleToObject<Base> : Base) extends infer _Base // Remove non-numeric keys from arrays ? IfNotAnyOrNever<_Base, _ConditionalKeys<_Base, Condition>, keyof _Base> : never; type _ConditionalKeys<Base, Condition> = keyof { [ Key in (keyof Base & {}) as // `& {}` prevents homomorphism ExtendsStrict<Base[Key], Condition> extends true ? Key : never ]: never }; export {};