import { isType } from '../internals'; import { isEmptyArray, isTuple } from '../arrays-and-tuples/infrastructure'; import { equals } from '../comparison/infrastructure'; import { $keyof, SerializableBySelf, waitFor } from '../generals/infrastructure'; import { nonUndefined } from '../undefined/infrastructure'; import { assign } from './app'; import { empty_object_key } from './domain'; export * from './app/ModifyPlusCombinations'; /** @deprecated use offical type PropertyKey instead */ export type KeyOfObject = PropertyKey; declare global { /** * Allow only objects (no primitives, no arrays, no functions), * This have a bug when using interfaces, so maybe you wanna use strictObject instead. * */ type unknownObject = { [key in PropertyKey]: unknown; }; /** Allow only objects (no primitives, no arrays, no functions). */ type strictObject = object & { length?: never; }; /** @warning `any` less primitive values. Try no use it. */ type anyObject = { [key in PropertyKey]: any; }; type emptyObject = { [empty_object_key]?: never; }; /** anyConstructor */ type Constructor = new (...args: any[]) => T; } /** * todo description */ export type toPlain = { [K in keyof T as T[K] extends anyFunction ? never : K]: T[K]; }; /** * todo description */ export type toJSON = _toJSON & {}; type _toJSON> = R extends SerializableBySelf ? R : Error<'Can not serialize this object.'>; /** * Return true if type is of type object array or function * if you are searching for only object use IsStrictObject instead. */ export type isObject = isType; /** * Return true if type is of type object ignoring arrays and functions. */ export type isStrictObject = isType; /** * Same as `modify` but less pretty and preserving the context of `this`. * This can't override `()` and `new()` properties. */ export type modifyInterface = waitFor>; /** * Allow modify interfaces or object types without the restrictions of use `extends` or `&` operator. */ export type modify = $if & isStrictObject, { then: prettify>; else: T; }>; /** * @deprecated will be removed in 4.0 * Allow modify interfaces or object types without the restrictions of use `extends` or `&` operator * Creates a Union Discrimated Type with the overrides + the keys pased for modify the object. */ export type modifyByKey = $if & isStrictObject, { then: prettify<({ [_ in KeyToDiscrimitate]?: undefined; } & T) | { [Key in keyof U]: { [_ in KeyToDiscrimitate]: Key; } & modify; }[keyof U]>; else: T; }>; /** * Recreate complex types for readability. * Do not change nothing, return the same type. */ export type prettify = { [K in keyof T]: T[K]; } & {}; /** * Pick properties from an object type `T` whose values match any of the types specified in `ValuesToPick`. * * @template Type - The original type to pick properties from. * @template ValuesToPick - A tuple of the types of the values you want to pick. * * @example * type T1 = { a: string; b: number; c: string | number; }; * type R1 = pickByValue; * // ^? { a: string; b: number; } * type R2 = pickByValue; * // ^? { c: string | number; } */ export type pickByValue = $if> | isEmptyArray, { then: prettify<_result>; else: ValuesToPick extends [infer X, ...infer Rest] ? pickByValue, { then: Key; else: never; }>]: Type[Key]; }> : never; }>; /** * Returns if the object can be `{}` * @example * type A = CanBeEmptyObject<{ a?: 'a'; b?: 'b';}> * // ^? true * type B = CanBeEmptyObject<{ a?: 'a'; b: 'b';}> * // ^? false b is required. */ export type canBeEmptyObject = [{}] extends [Type] ? true : false; /** * Returns the keys of an object which are `readonly`. * @example * type U = getReadonlyKeys<{ a: number, readonly b: string }>; * // ^? "b" */ export type getReadonlyKeys = { [Key in keyof Type]-?: $if, { then: Key; else: never; }>; }[keyof Type]; /** * Returns the keys of an object which are not `readonly`. * @example * type U = getNoReadonlyKeys<{ a: number, readonly b: string }>; * // ^? "a" */ export type getNoReadonlyKeys = { [Key in keyof Type]-?: $if, { then: Key; else: never; }>; }[keyof Type]; /** * Returns the required keys of an object * @example * type U = getRequiredKeys<{ a?: 'a'; b: 'b'; c: 'a' }> * // ^? "b" | "c" */ export type getRequiredKeys = { [Key in keyof Type]-?: $if>, { then: Key; else: never; }>; }[keyof Type]; /** * Returns the optional keys of an object * @example * type U = getOptionalKeys<{ a?: 'a'; b?: 'b'; c: 'a' }> * // ^? "a" | "b" */ export type getOptionalKeys = { [Key in keyof Type]-?: $if, { then: Key; else: never; }>; }[keyof Type]; /** * Return if the object have a specifit property. * @example * type U = hasProperty<{ a?: 'a'; b?: 'b'; c: 'c' }, 'c'> * // ^? true */ export type hasProperty = K extends $keyof ? true : false; /** * Convert specific properties of an object `T` to readonly. * @example * type U = someToReadonly<{ a: 'a'; b: 'b' }, 'a'> * // ^? { readonly a: 'a', b: 'b' } */ export type someToReadonly> = prettify & { readonly [key in K]: T[K]; }>; /** * Remove readonly to specific properties of an object `T`. * @example * type U = someToWritable<{ readonly a: 'a'; readonly b: 'b' }, 'a'> * // ^? { a: 'a', readonly b: 'b' } */ export type someToWritable> = prettify & { -readonly [key in K]: T[K]; }>; /** * Convert specific properties of an object `T` to optional. * @example * type U = someToPartial<{ a: 'a'; b: 'b' }, 'a'> * // ^? { a?: 'a', b: 'b' } */ export type someToPartial> = prettify & { [key in K]?: T[K]; }>; /** * Make specific properties of an object `T` required. * @example * type U = someToRequired<{ a?: 'a'; b?: 'b' }, 'a'> * // ^? { a: 'a', b: 'b' } */ export type someToRequired> = prettify & { [key in K]-?: nonUndefined; }>; /** * Converts a tuple to an object. * * @example * type a = TupleToObject<[string, number]> * // ^? { 0: string; 1: number; } */ export type TupleToObject = { [K in Exclude]: T[K]; };