UNPKG

@strapi/types

Version:

Shared typescript types for Strapi internal use

180 lines 6.62 kB
/** * Extracts object's (`TValue`) keys where the key's value type extends the given `TTest` type. * * @template TValue - The original object type. * @template TTest - The test type. Keys of TValue having values that extend this type are extracted. * @template TExtract - An optional constraint for the keys of TValue. * * @example * * // Here TValue is `{ foo: 'bar', bar: 'foo', foobar: 2 }` and TTest is `string`. * // So it extracts keys `foo` and `bar`, because their values are string type. * type keys = KeysBy<{ foo: 'bar', bar: 'foo', foobar: 2 }, string> // 'foo' | 'bar' * * @example * * // Here TValue is `{ foo: { x: 'foo' }, bar: { x: 'bar' }, other: { x: '42' } }` and TTest is `{ x: 'foo' | 'bar' }`. * // So it extracts keys `foo` and `bar`, because their values are extending `{ x: 'foo' | 'bar' }`. * type Base = { x: 'foo' | 'bar' }; * type Obj = { foo: { x: 'foo' }, bar: { x: 'bar' }, other: { x: '42' } }; * type X = KeysBy<Obj, Base> // 'foo' | 'bar' * * @see {@link KeysExcept} * @see {@link PickBy} */ export type KeysBy<TValue, TTest, TExtract extends keyof any = keyof any> = { [key in keyof TValue & TExtract]: TValue[key] extends TTest ? key : never; }[keyof TValue & TExtract]; /** * Extracts the keys of a given object ({@link TValue}). It includes only those keys which do not map to a value of type {@link TTest}`. * * @template TValue - The object whose keys are to be examined and selectively retrieved * @template TTest - The type of value to be used as an exclusion criterion for selecting keys from `TValue` * @template TExtract - An optional union of keys to constrain the keys that are being examined. If not provided, it defaults to examining all keys in `TValue`. * * @example * ```typescript * // In this example, KeysExcept is used to fetch keys from the object which do not have string type values * type ExampleType = { foo: 'bar', bar: 'foo', foobar: 2 } * type ResultType = KeysExcept<ExampleType, string> * // The resulting type is "foobar" * ``` * * @example * ```typescript * // In this example, we use a base type to define allowed value types and only fetch those keys from the object that have values not extending the base type * type Base = { x: 'foo' | 'bar' }; * type Obj = { foo: { x: 'foo' }, bar: { x: 'bar' }, other: { x: '42' } }; * type X = KeysBy<Obj, Base> * // The resulting type is "other" * ``` */ export type KeysExcept<TValue, TTest, TExtract extends keyof any = keyof any> = { [key in keyof TValue & TExtract]: TValue[key] extends TTest ? never : key; }[keyof TValue & TExtract]; /** * Select properties from an object ({@link TValue}), only if their types extend a specific test type ({@link TTest}). * * @template TValue - The object type from which properties are selected. * @template TTest - The test type. Properties of TValue extending this type are selected. * * @example * * // If we have this: * type FruitAttributes = { color: string, taste: string, weight: number, isOrganic: boolean }; * * // And we use `PickBy` like so: * type StringAttributes = PickBy<FruitAttributes, string>; * * // Then, `StringAttributes` will equal: `{ color: string, taste: string }` */ export type PickBy<TValue, TTest> = Pick<TValue, KeysBy<TValue, TTest>>; /** * Creates a new type from a given type ({@link TValue}), and select specific * keys ({@link TKeys}) to be optionally present in the new type. * * @template TValue The original type of object. * @template TKeys A union of selected {@link TValue} object keys that should be partial/optional in the new type. * * @example * ```typescript * type Person = { * name: string; * age: number; * }; * * type PartialAgePerson = PartialBy<Person, 'age'>; * * // the type PartialAgePerson is now equivalent to: * // { * // name: string; * // age?: number; * // } * ``` */ export type PartialBy<TValue, TKeys extends keyof TValue> = Omit<TValue, TKeys> & Partial<Pick<TValue, TKeys>>; /** * Extracts all unique values from a given object as a union type. * * @template TObject - An object from which values are to be extracted. It must extend the `object` type. * * @remark * It works with non-primitive values as well. Hence, if a value is an object, it is included as is. Primitive types are included directly. * * @example * With a simple object: * ```TypeScript * type SimpleExample = Values<{ * a: 'one', * b: 'two', * c: 3 * }>; * // Result: 'one' | 'two' | 3 * ``` * * @example * With complex (non-primitive) values in an object: * ```TypeScript * type ComplexExample = Values<{ * a: { x: 10 }, * b: { y: 'twenty' }, * c: { z: true } * }>; * // Result: { x: 10 } | { y: 'twenty' } | { z: true } * ``` */ export type Values<TObject extends object> = TObject[keyof TObject]; /** * Provides a way to set deeply-nested properties within `TObject` to optional. * * @template TObject Type of the object that will become deeply partial. * * @example * ```typescript * interface Person { * name: string; * age: number; * address: { * city: string; * street: string; * postalCode: number; * }; * } * * const partialPerson: DeepPartial<Person> = {}; // This is now valid * * // You can assign partially filled objects * const anotherPerson: DeepPartial<Person> = { * name: 'John', * address: { * city: 'San Francisco', * // street and postal code are optional * } * } * ``` */ export type DeepPartial<TObject> = TObject extends object ? { [TKey in keyof TObject]?: DeepPartial<TObject[TKey]>; } : TObject; /** * Creates a new type by replacing properties of {@link TObject} with properties from {@link TNew}. * * This is particularly useful to fine-tune the shape of an object type by altering some of its properties while keeping the rest intact. * * @template TObject - A type that extends `object`. This should be the original type that you intend to transform. * @template TNew - A partial type of {@link TObject} where keys are replaced with new types. * * @example * * ```typescript * type Original = { foo: number, bar: number}; // Declare original type * type Transformation = { foo: string }; // Declare keys to replace from original type * * type Result = Replace<Original, Transformation>; * // The transformed type now becomes { foo: string, bar: number } * ``` */ export type Replace<TObject extends object, TNew extends Partial<{ [key in keyof TObject]: unknown; }>> = Omit<TObject, keyof TNew> & TNew; //# sourceMappingURL=object.d.ts.map