import type { IsNever, Simplify } from "type-fest"; export type { Simplify, Primitive, LiteralUnion, IsAny } from "type-fest"; /** * Extracts the key from the object type, same as TObj[TKey] * If the key doesn't exist, returns a TypeMismatchError */ export type Get = TKey extends keyof TObj ? TObj[TKey] : TypeMismatchError<{ error: "Invalid property"; expected: keyof TObj; actual: TKey; }>; /** * Simplifies a type alias to just the primitive types. * Improves IDE experience. * @example * type Nested = { nested: "NESTED" }; * type Foo = Partial<{ a: "A", b: "B", nested: Nested }>; * * type FooSimple = SimplifyDeep; * // Shows as "type fooSimple = { a?: "A", b?: "B", nested?: {nested: "NESTED" } }" */ export type SimplifyDeep = T extends object ? T extends infer O ? { [K in keyof O]: SimplifyDeep; } : never : T; export type Override = Omit & TOverrides; export type TypeMismatchError = { error: TError["error"]; expected: Simplify; actual: Simplify; }; /** * Extracts all TypeMismatchError's from the projection result, * making it easy to report these errors. * Returns a string of error messages, * or `never` if there are no errors. */ export type ExtractTypeMismatchErrors = ValueOf<{ [TKey in StringKeys]: TypeMismatchError extends TProjectionResult[TKey] ? `Error in "${TKey}": ${Extract["error"]}` : never; }>; /** * Returns a union of all value types in the object */ export type ValueOf = T[keyof T]; /** * Returns a union of the [Key, Value] pairs of the object. * @example * EntriesOf<{ foo: "FOO", bar: "BAR" }> * // Results: ["foo", "FOO"] | ["bar", "BAR"] */ export type EntriesOf = ValueOf<{ [Key in StringKeys]: [Key, T[Key]]; }>; /** * Returns the intersection (&) of the values of a type. * * Similar to ValueOf, which returns the union (|) of the values. * * @example * IntersectionOfValues<{ * foo: { foo: "FOO" } | { }, * bar: { bar: "BAR" } | { }, * }> == { } | { foo: "FOO" } | { bar: "BAR" } | { foo: "FOO", bar: "BAR" } */ export type IntersectionOfValues = { [P in keyof T]: (x: T[P]) => void; }[keyof T] extends (x: infer ValueIntersection) => void ? ValueIntersection : never; /** * Excludes symbol and number from keys, so that you only have strings. */ export type StringKeys = Exclude; /** * Excludes the first item in a tuple */ export type ButFirst> = T extends [any, ...infer Rest] ? Rest : never; /** * A completely empty object. */ export type Empty = Record; export declare function keys(obj: T): Array>; export declare function notNull(value: T | null): value is T; export declare function pick(obj: T, keys: TKeys[]): Pick; /** * Replaces undefined with null. * @example * UndefinedToNull == Foo | null; * UndefinedToNull == Foo; */ export type UndefinedToNull = T extends undefined ? NonNullable | null : T; /** * When we map projection results, we return TypeMismatchError's * for any fields that have an invalid mapping configuration. * However, this does not cause TypeScript to throw any errors. * * In order to get TypeScript to complain about these invalid mappings, * we will "require" an extra parameter, which will reveal the error messages. */ export type RequireAFakeParameterIfThereAreTypeMismatchErrors> = IsNever<_Errors> extends true ? [] : [_Errors] | ["⛔️ Error: this projection has type mismatches: ⛔️"];