UNPKG

react-querybuilder

Version:

React Query Builder component for constructing queries and filters, with utilities for executing them in various database and evaluation contexts

1,710 lines (1,323 loc) 231 kB
import * as React from "react"; import { ChangeEvent, ComponentType, Context, ForwardRefExoticComponent, MouseEvent, ReactNode, Ref, RefAttributes } from "react"; import { ReactReduxContextValue, TypedUseSelectorHook } from "react-redux"; import { EnhancedStore, StoreEnhancer, ThunkDispatch, Tuple as Tuple$1, UnknownAction } from "@reduxjs/toolkit"; import { JsonLogicAll, JsonLogicAnd, JsonLogicDoubleNegation, JsonLogicEqual, JsonLogicGreaterThan, JsonLogicGreaterThanOrEqual, JsonLogicInArray, JsonLogicInString, JsonLogicLessThan, JsonLogicLessThanOrEqual, JsonLogicNegation, JsonLogicNone, JsonLogicNotEqual, JsonLogicOr, JsonLogicSome, JsonLogicStrictEqual, JsonLogicStrictNotEqual, JsonLogicVar, ReservedOperations as JsonLogicReservedOperations, RulesLogic, RulesLogic as JsonLogicRulesLogic } from "json-logic-js"; import { Column, Operators, SQL, Table } from "drizzle-orm"; import { WhereOptions } from "sequelize"; //#region ../core/src/types/type-fest/is-equal.d.ts /** Returns a boolean for whether the two given types are equal. @link https://github.com/microsoft/TypeScript/issues/27024#issuecomment-421529650 @link https://stackoverflow.com/questions/68961864/how-does-the-equals-work-in-typescript/68963796#68963796 Use-cases: - If you want to make a conditional branch based on the result of a comparison of two types. @example ``` import type {IsEqual} from 'type-fest'; // This type returns a boolean for whether the given array includes the given item. // `IsEqual` is used to compare the given array at position 0 and the given item and then return true if they are equal. type Includes<Value extends readonly any[], Item> = Value extends readonly [Value[0], ...infer rest] ? IsEqual<Value[0], Item> extends true ? true : Includes<rest, Item> : false; ``` @group type-fest */ type IsEqual<A, B> = (<G>() => G extends A & G | G ? 1 : 2) extends (<G>() => G extends B & G | G ? 1 : 2) ? true : false; //#endregion //#region ../core/src/types/type-fest/and.d.ts /** Returns a boolean for whether two given types are both true. Use-case: Constructing complex conditional types where multiple conditions must be satisfied. @example ``` import type {And} from 'type-fest'; And<true, true>; //=> true And<true, false>; //=> false ``` @see {@link Or} @group type-fest */ type And<A extends boolean, B extends boolean> = [A, B][number] extends true ? true : true extends [IsEqual<A, false>, IsEqual<B, false>][number] ? false : never; //#endregion //#region ../core/src/types/type-fest/is-never.d.ts /** Returns a boolean for whether the given type is `never`. @link https://github.com/microsoft/TypeScript/issues/31751#issuecomment-498526919 @link https://stackoverflow.com/a/53984913/10292952 @link https://www.zhenghao.io/posts/ts-never Useful in type utilities, such as checking if something does not occur. @example ``` import type {IsNever, And} from 'type-fest'; // https://github.com/andnp/SimplyTyped/blob/master/src/types/strings.ts type AreStringsEqual<A extends string, B extends string> = And< IsNever<Exclude<A, B>> extends true ? true : false, IsNever<Exclude<B, A>> extends true ? true : false >; type EndIfEqual<I extends string, O extends string> = AreStringsEqual<I, O> extends true ? never : void; function endIfEqual<I extends string, O extends string>(input: I, output: O): EndIfEqual<I, O> { if (input === output) { process.exit(0); } } endIfEqual('abc', 'abc'); //=> never endIfEqual('abc', '123'); //=> void ``` @group type-fest */ type IsNever<T> = [T] extends [never] ? true : false; //#endregion //#region ../core/src/types/type-fest/if-never.d.ts /** An if-else-like type that resolves depending on whether the given type is `never`. @see {@link IsNever} @example ``` import type {IfNever} from 'type-fest'; type ShouldBeTrue = IfNever<never>; //=> true type ShouldBeBar = IfNever<'not never', 'foo', 'bar'>; //=> 'bar' ``` @group type-fest */ type IfNever$1<T, TypeIfNever = true, TypeIfNotNever = false> = (IsNever<T> extends true ? TypeIfNever : TypeIfNotNever); //#endregion //#region ../core/src/types/type-fest/unknown-array.d.ts /** Represents an array with `unknown` value. Use case: You want a type that all arrays can be assigned to, but you don't care about the value. @example ``` import type {UnknownArray} from 'type-fest'; type IsArray<T> = T extends UnknownArray ? true : false; type A = IsArray<['foo']>; //=> true type B = IsArray<readonly number[]>; //=> true type C = IsArray<string>; //=> false ``` @group type-fest */ type UnknownArray = readonly unknown[]; //#endregion //#region ../core/src/types/type-fest/internal/array.d.ts /** Returns whether the given array `T` is readonly. @group type-fest */ type IsArrayReadonly<T extends UnknownArray> = IfNever$1<T, false, T extends unknown[] ? false : true>; /** An if-else-like type that resolves depending on whether the given array is readonly. @see {@link IsArrayReadonly} @example ``` import type {ArrayTail} from 'type-fest'; type ReadonlyPreservingArrayTail<TArray extends readonly unknown[]> = ArrayTail<TArray> extends infer Tail ? IfArrayReadonly<TArray, Readonly<Tail>, Tail> : never; type ReadonlyTail = ReadonlyPreservingArrayTail<readonly [string, number, boolean]>; //=> readonly [number, boolean] type NonReadonlyTail = ReadonlyPreservingArrayTail<[string, number, boolean]>; //=> [number, boolean] type ShouldBeTrue = IfArrayReadonly<readonly unknown[]>; //=> true type ShouldBeBar = IfArrayReadonly<unknown[], 'foo', 'bar'>; //=> 'bar' ``` @group type-fest */ type IfArrayReadonly<T extends UnknownArray, TypeIfArrayReadonly = true, TypeIfNotArrayReadonly = false> = IsArrayReadonly<T> extends infer Result ? Result extends true ? TypeIfArrayReadonly : TypeIfNotArrayReadonly : never; //#endregion //#region ../core/src/types/type-fest/internal/characters.d.ts /** @group type-fest */ type Whitespace = " " | "\n" | "\v" | "\f" | "\r" | " " | "…" | "\xA0" | " " | " " | " " | " " | " " | " " | " " | " " | " " | " " | " " | " " | "\u2028" | "\u2029" | " " | " " | " " | ""; //#endregion //#region ../core/src/types/type-fest/is-any.d.ts type NoInfer<T> = T extends infer U ? U : never; /** Returns a boolean for whether the given type is `any`. @link https://stackoverflow.com/a/49928360/1490091 Useful in type utilities, such as disallowing `any`s to be passed to a function. @example ``` import type {IsAny} from 'type-fest'; const typedObject = {a: 1, b: 2} as const; const anyObject: any = {a: 1, b: 2}; function get<O extends (IsAny<O> extends true ? {} : Record<string, number>), K extends keyof O = keyof O>(obj: O, key: K) { return obj[key]; } const typedA = get(typedObject, 'a'); //=> 1 const anyA = get(anyObject, 'a'); //=> any ``` @group type-fest */ type IsAny<T> = 0 extends 1 & NoInfer<T> ? true : false; //#endregion //#region ../core/src/types/type-fest/primitive.d.ts /** Matches any [primitive value](https://developer.mozilla.org/en-US/docs/Glossary/Primitive). @group type-fest */ type Primitive = null | undefined | string | number | boolean | symbol | bigint; //#endregion //#region ../core/src/types/type-fest/is-float.d.ts /** Returns a boolean for whether the given number is a float, like `1.5` or `-1.5`. Use-case: - If you want to make a conditional branch based on the result of whether a number is a float or not. @example ``` import type {IsFloat, PositiveInfinity} from "type-fest"; type A = IsFloat<1.5>; //=> true type B = IsFloat<-1.5>; //=> true type C = IsFloat<1e-7>; //=> true type D = IsFloat<1.0>; //=> false type E = IsFloat<PositiveInfinity>; //=> false type F = IsFloat<1.23e+21>; //=> false ``` @group type-fest */ type IsFloat<T> = T extends number ? `${T}` extends `${number}e${infer E extends "-" | "+"}${number}` ? E extends "-" ? true : false : `${T}` extends `${number}.${number}` ? true : false : false; //#endregion //#region ../core/src/types/type-fest/is-integer.d.ts /** Returns a boolean for whether the given number is an integer, like `-5`, `1.0`, or `100`. Use-case: - If you want to make a conditional branch based on the result of whether a number is an integer or not. @example ``` import type {IsInteger, PositiveInfinity} from "type-fest"; type A = IsInteger<1>; //=> true type B = IsInteger<1.0>; //=> true type C = IsInteger<-1>; //=> true type D = IsInteger<0b10>; //=> true type E = IsInteger<0o10>; //=> true type F = IsInteger<0x10>; //=> true type G = IsInteger<1.23+21>; //=> true type H = IsInteger<1.5>; //=> false type I = IsInteger<PositiveInfinity>; //=> false type J = IsInteger<1e-7>; //=> false ``` @group type-fest */ type IsInteger<T> = T extends bigint ? true : T extends number ? number extends T ? false : T extends PositiveInfinity | NegativeInfinity ? false : Not<IsFloat<T>> : false; //#endregion //#region ../core/src/types/type-fest/numeric.d.ts /** @group type-fest */ type Numeric = number | bigint; /** @group type-fest */ type Zero = 0 | 0n; /** Matches the hidden `Infinity` type. Please upvote [this issue](https://github.com/microsoft/TypeScript/issues/32277) if you want to have this type as a built-in in TypeScript. @see NegativeInfinity @group type-fest */ type PositiveInfinity = 1e999; /** Matches the hidden `-Infinity` type. Please upvote [this issue](https://github.com/microsoft/TypeScript/issues/32277) if you want to have this type as a built-in in TypeScript. @see PositiveInfinity @group type-fest */ type NegativeInfinity = -1e999; /** A finite `number`. You can't pass a `bigint` as they are already guaranteed to be finite. Use-case: Validating and documenting parameters. Note: This can't detect `NaN`, please upvote [this issue](https://github.com/microsoft/TypeScript/issues/28682) if you want to have this type as a built-in in TypeScript. @example ``` import type {Finite} from 'type-fest'; declare function setScore<T extends number>(length: Finite<T>): void; ``` @group type-fest */ type Finite<T extends number> = T extends PositiveInfinity | NegativeInfinity ? never : T; /** A `number` that is an integer. Use-case: Validating and documenting parameters. @example ``` type Integer = Integer<1>; //=> 1 type IntegerWithDecimal = Integer<1.0>; //=> 1 type NegativeInteger = Integer<-1>; //=> -1 type Float = Integer<1.5>; //=> never // Supports non-decimal numbers type OctalInteger: Integer<0o10>; //=> 0o10 type BinaryInteger: Integer<0b10>; //=> 0b10 type HexadecimalInteger: Integer<0x10>; //=> 0x10 ``` @example ``` import type {Integer} from 'type-fest'; declare function setYear<T extends number>(length: Integer<T>): void; ``` @see NegativeInteger @see NonNegativeInteger @group type-fest */ type Integer<T> = T extends unknown ? IsInteger<T> extends true ? T : never : never; /** A `number` that is not an integer. Use-case: Validating and documenting parameters. It does not accept `Infinity`. @example ``` import type {Float} from 'type-fest'; declare function setPercentage<T extends number>(length: Float<T>): void; ``` @see Integer @group type-fest */ type Float<T> = T extends unknown ? IsFloat<T> extends true ? T : never : never; /** A negative (`-∞ < x < 0`) `number` that is not an integer. Equivalent to `Negative<Float<T>>`. Use-case: Validating and documenting parameters. @see Negative @see Float @group type-fest */ type NegativeFloat<T extends number> = Negative<Float<T>>; /** A negative `number`/`bigint` (`-∞ < x < 0`) Use-case: Validating and documenting parameters. @see NegativeInteger @see NonNegative @group type-fest */ type Negative<T extends Numeric> = T extends Zero ? never : `${T}` extends `-${string}` ? T : never; /** A negative (`-∞ < x < 0`) `number` that is an integer. Equivalent to `Negative<Integer<T>>`. You can't pass a `bigint` as they are already guaranteed to be integers, instead use `Negative<T>`. Use-case: Validating and documenting parameters. @see Negative @see Integer @group type-fest */ type NegativeInteger<T extends number> = Negative<Integer<T>>; /** A non-negative `number`/`bigint` (`0 <= x < ∞`). Use-case: Validating and documenting parameters. @see NonNegativeInteger @see Negative @example ``` import type {NonNegative} from 'type-fest'; declare function setLength<T extends number>(length: NonNegative<T>): void; ``` @group type-fest */ type NonNegative<T extends Numeric> = T extends Zero ? T : Negative<T> extends never ? T : never; /** A non-negative (`0 <= x < ∞`) `number` that is an integer. Equivalent to `NonNegative<Integer<T>>`. You can't pass a `bigint` as they are already guaranteed to be integers, instead use `NonNegative<T>`. Use-case: Validating and documenting parameters. @see NonNegative @see Integer @example ``` import type {NonNegativeInteger} from 'type-fest'; declare function setLength<T extends number>(length: NonNegativeInteger<T>): void; ``` @group type-fest */ type NonNegativeInteger<T extends number> = NonNegative<Integer<T>>; /** Returns a boolean for whether the given number is a negative number. @see Negative @example ``` import type {IsNegative} from 'type-fest'; type ShouldBeFalse = IsNegative<1>; type ShouldBeTrue = IsNegative<-1>; ``` @group type-fest */ type IsNegative<T extends Numeric> = T extends Negative<T> ? true : false; //#endregion //#region ../core/src/types/type-fest/is-literal.d.ts /** Returns a boolean for whether the given type `T` is the specified `LiteralType`. @link https://stackoverflow.com/a/52806744/10292952 @example ``` LiteralCheck<1, number> //=> true LiteralCheck<number, number> //=> false LiteralCheck<1, string> //=> false ``` */ type LiteralCheck<T, LiteralType extends Primitive> = (IsNever<T> extends false ? [T] extends [LiteralType & infer U] ? [U] extends [LiteralType] ? [LiteralType] extends [U] ? false : true : false : false : false); /** Returns a boolean for whether the given type `T` is one of the specified literal types in `LiteralUnionType`. @example ``` LiteralChecks<1, Numeric> //=> true LiteralChecks<1n, Numeric> //=> true LiteralChecks<bigint, Numeric> //=> false ``` */ type LiteralChecks<T, LiteralUnionType> = (IsNotFalse<LiteralUnionType extends Primitive ? LiteralCheck<T, LiteralUnionType> : never>); /** Returns a boolean for whether the given type is a `string` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types). Useful for: - providing strongly-typed string manipulation functions - constraining strings to be a string literal - type utilities, such as when constructing parsers and ASTs The implementation of this type is inspired by the trick mentioned in this [StackOverflow answer](https://stackoverflow.com/a/68261113/420747). @example ``` import type {IsStringLiteral} from 'type-fest'; type CapitalizedString<T extends string> = IsStringLiteral<T> extends true ? Capitalize<T> : string; // https://github.com/yankeeinlondon/native-dash/blob/master/src/capitalize.ts function capitalize<T extends Readonly<string>>(input: T): CapitalizedString<T> { return (input.slice(0, 1).toUpperCase() + input.slice(1)) as CapitalizedString<T>; } const output = capitalize('hello, world!'); //=> 'Hello, world!' ``` @example ``` // String types with infinite set of possible values return `false`. import type {IsStringLiteral} from 'type-fest'; type AllUppercaseStrings = IsStringLiteral<Uppercase<string>>; //=> false type StringsStartingWithOn = IsStringLiteral<`on${string}`>; //=> false // This behaviour is particularly useful in string manipulation utilities, as infinite string types often require separate handling. type Length<S extends string, Counter extends never[] = []> = IsStringLiteral<S> extends false ? number // return `number` for infinite string types : S extends `${string}${infer Tail}` ? Length<Tail, [...Counter, never]> : Counter['length']; type L1 = Length<Lowercase<string>>; //=> number type L2 = Length<`${number}`>; //=> number ``` @group type-fest */ type IsStringLiteral<T> = IfNever$1<T, false, T extends string ? {} extends Record<T, never> ? false : true : false>; /** Returns a boolean for whether the given type is a `number` or `bigint` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types). Useful for: - providing strongly-typed functions when given literal arguments - type utilities, such as when constructing parsers and ASTs @example ``` import type {IsNumericLiteral} from 'type-fest'; // https://github.com/inocan-group/inferred-types/blob/master/src/types/boolean-logic/EndsWith.ts type EndsWith<TValue, TEndsWith extends string> = TValue extends string ? IsStringLiteral<TEndsWith> extends true ? IsStringLiteral<TValue> extends true ? TValue extends `${string}${TEndsWith}` ? true : false : boolean : boolean : TValue extends number ? IsNumericLiteral<TValue> extends true ? EndsWith<`${TValue}`, TEndsWith> : false : false; function endsWith<Input extends string | number, End extends string>(input: Input, end: End) { return `${input}`.endsWith(end) as EndsWith<Input, End>; } endsWith('abc', 'c'); //=> true endsWith(123456, '456'); //=> true const end = '123' as string; endsWith('abc123', end); //=> boolean ``` @group type-fest */ type IsNumericLiteral<T> = LiteralChecks<T, Numeric>; /** Returns a boolean for whether the given type is a `true` or `false` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types). Useful for: - providing strongly-typed functions when given literal arguments - type utilities, such as when constructing parsers and ASTs @example ``` import type {IsBooleanLiteral} from 'type-fest'; const id = 123; type GetId<AsString extends boolean> = IsBooleanLiteral<AsString> extends true ? AsString extends true ? `${typeof id}` : typeof id : number | string; function getId<AsString extends boolean = false>(options?: {asString: AsString}) { return (options?.asString ? `${id}` : id) as GetId<AsString>; } const numberId = getId(); //=> 123 const stringId = getId({asString: true}); //=> '123' declare const runtimeBoolean: boolean; const eitherId = getId({asString: runtimeBoolean}); //=> number | string ``` @group type-fest */ type IsBooleanLiteral<T> = LiteralCheck<T, boolean>; /** Returns a boolean for whether the given type is a `symbol` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types). Useful for: - providing strongly-typed functions when given literal arguments - type utilities, such as when constructing parsers and ASTs @example ``` import type {IsSymbolLiteral} from 'type-fest'; type Get<Obj extends Record<symbol, number>, Key extends keyof Obj> = IsSymbolLiteral<Key> extends true ? Obj[Key] : number; function get<Obj extends Record<symbol, number>, Key extends keyof Obj>(o: Obj, key: Key) { return o[key] as Get<Obj, Key>; } const symbolLiteral = Symbol('literal'); const symbolValue: symbol = Symbol('value'); get({[symbolLiteral]: 1} as const, symbolLiteral); //=> 1 get({[symbolValue]: 1} as const, symbolValue); //=> number ``` @group type-fest */ type IsSymbolLiteral<T> = LiteralCheck<T, symbol>; /** Helper type for `IsLiteral`. */ type IsLiteralUnion<T> = IsStringLiteral<T> | IsNumericLiteral<T> | IsBooleanLiteral<T> | IsSymbolLiteral<T>; /** Returns a boolean for whether the given type is a [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types). Useful for: - providing strongly-typed functions when given literal arguments - type utilities, such as when constructing parsers and ASTs @example ``` import type {IsLiteral} from 'type-fest'; // https://github.com/inocan-group/inferred-types/blob/master/src/types/string-literals/StripLeading.ts export type StripLeading<A, B> = A extends string ? B extends string ? IsLiteral<A> extends true ? string extends B ? never : A extends `${B & string}${infer After}` ? After : A : string : A : A; function stripLeading<Input extends string, Strip extends string>(input: Input, strip: Strip) { return input.replace(`^${strip}`, '') as StripLeading<Input, Strip>; } stripLeading('abc123', 'abc'); //=> '123' const str = 'abc123' as string; stripLeading(str, 'abc'); //=> string ``` @group type-fest */ type IsLiteral<T> = IsPrimitive<T> extends true ? IsNotFalse<IsLiteralUnion<T>> : false; //#endregion //#region ../core/src/types/type-fest/trim.d.ts /** Remove spaces from the left side. */ type TrimLeft<V extends string> = V extends `${Whitespace}${infer R}` ? TrimLeft<R> : V; /** Remove spaces from the right side. */ type TrimRight<V extends string> = V extends `${infer R}${Whitespace}` ? TrimRight<R> : V; /** Remove leading and trailing spaces from a string. @example ``` import type {Trim} from 'type-fest'; Trim<' foo '> //=> 'foo' ``` @group type-fest */ type Trim<V extends string> = TrimLeft<TrimRight<V>>; //#endregion //#region ../core/src/types/type-fest/or.d.ts /** Returns a boolean for whether either of two given types are true. Use-case: Constructing complex conditional types where multiple conditions must be satisfied. @example ``` import type {Or} from 'type-fest'; Or<true, false>; //=> true Or<false, false>; //=> false ``` @see {@link And} @group type-fest */ type Or<A extends boolean, B extends boolean> = [A, B][number] extends false ? false : true extends [IsEqual<A, true>, IsEqual<B, true>][number] ? true : never; //#endregion //#region ../core/src/types/type-fest/greater-than.d.ts /** Returns a boolean for whether a given number is greater than another number. @example ``` import type {GreaterThan} from 'type-fest'; GreaterThan<1, -5>; //=> true GreaterThan<1, 1>; //=> false GreaterThan<1, 5>; //=> false ``` @group type-fest */ type GreaterThan<A extends number, B extends number> = A extends number ? B extends number ? number extends A | B ? never : [IsEqual<A, PositiveInfinity>, IsEqual<A, NegativeInfinity>, IsEqual<B, PositiveInfinity>, IsEqual<B, NegativeInfinity>] extends infer R extends [boolean, boolean, boolean, boolean] ? Or<And<IsEqual<R[0], true>, IsEqual<R[2], false>>, And<IsEqual<R[3], true>, IsEqual<R[1], false>>> extends true ? true : Or<And<IsEqual<R[1], true>, IsEqual<R[3], false>>, And<IsEqual<R[2], true>, IsEqual<R[0], false>>> extends true ? false : true extends R[number] ? false : [IsNegative<A>, IsNegative<B>] extends infer R extends [boolean, boolean] ? [true, false] extends R ? false : [false, true] extends R ? true : [false, false] extends R ? PositiveNumericStringGt<`${A}`, `${B}`> : PositiveNumericStringGt<`${NumberAbsolute<B>}`, `${NumberAbsolute<A>}`> : never : never : never : never; //#endregion //#region ../core/src/types/type-fest/greater-than-or-equal.d.ts /** Returns a boolean for whether a given number is greater than or equal to another number. @example ``` import type {GreaterThanOrEqual} from 'type-fest'; GreaterThanOrEqual<1, -5>; //=> true GreaterThanOrEqual<1, 1>; //=> true GreaterThanOrEqual<1, 5>; //=> false ``` @group type-fest */ type GreaterThanOrEqual<A extends number, B extends number> = number extends A | B ? never : A extends B ? true : GreaterThan<A, B>; //#endregion //#region ../core/src/types/type-fest/less-than.d.ts /** Returns a boolean for whether a given number is less than another number. @example ``` import type {LessThan} from 'type-fest'; LessThan<1, -5>; //=> false LessThan<1, 1>; //=> false LessThan<1, 5>; //=> true ``` @group type-fest */ type LessThan<A extends number, B extends number> = number extends A | B ? never : GreaterThanOrEqual<A, B> extends infer Result ? Result extends true ? false : true : never; //#endregion //#region ../core/src/types/type-fest/internal/tuple.d.ts /** Create a tuple type of the given length `<L>` and fill it with the given type `<Fill>`. If `<Fill>` is not provided, it will default to `unknown`. @link https://itnext.io/implementing-arithmetic-within-typescripts-type-system-a1ef140a6f6f @group type-fest */ type BuildTuple<L extends number, Fill = unknown, T extends readonly unknown[] = []> = number extends L ? Fill[] : L extends T["length"] ? T : BuildTuple<L, Fill, [...T, Fill]>; //#endregion //#region ../core/src/types/type-fest/internal/string.d.ts /** Converts a numeric string to a number. @example ``` type PositiveInt = StringToNumber<'1234'>; //=> 1234 type NegativeInt = StringToNumber<'-1234'>; //=> -1234 type PositiveFloat = StringToNumber<'1234.56'>; //=> 1234.56 type NegativeFloat = StringToNumber<'-1234.56'>; //=> -1234.56 type PositiveInfinity = StringToNumber<'Infinity'>; //=> Infinity type NegativeInfinity = StringToNumber<'-Infinity'>; //=> -Infinity ``` @group type-fest */ type StringToNumber<S extends string> = S extends `${infer N extends number}` ? N : S extends "Infinity" ? PositiveInfinity : S extends "-Infinity" ? NegativeInfinity : never; /** Returns an array of the characters of the string. @example ``` StringToArray<'abcde'>; //=> ['a', 'b', 'c', 'd', 'e'] StringToArray<string>; //=> never ``` @group type-fest */ type StringToArray<S extends string, Result extends string[] = []> = string extends S ? never : S extends `${infer F}${infer R}` ? StringToArray<R, [...Result, F]> : Result; /** Returns the length of the given string. @example ``` StringLength<'abcde'>; //=> 5 StringLength<string>; //=> never ``` @group type-fest */ type StringLength<S extends string> = string extends S ? never : StringToArray<S>["length"]; /** Returns a boolean for whether `A` represents a number greater than `B`, where `A` and `B` are both numeric strings and have the same length. @example ``` SameLengthPositiveNumericStringGt<'50', '10'>; //=> true SameLengthPositiveNumericStringGt<'10', '10'>; //=> false ``` */ type SameLengthPositiveNumericStringGt<A extends string, B extends string> = A extends `${infer FirstA}${infer RestA}` ? B extends `${infer FirstB}${infer RestB}` ? FirstA extends FirstB ? SameLengthPositiveNumericStringGt<RestA, RestB> : PositiveNumericCharacterGt<FirstA, FirstB> : never : false; type NumericString = "0123456789"; /** Returns a boolean for whether `A` is greater than `B`, where `A` and `B` are both positive numeric strings. @example ``` PositiveNumericStringGt<'500', '1'>; //=> true PositiveNumericStringGt<'1', '1'>; //=> false PositiveNumericStringGt<'1', '500'>; //=> false ``` @group type-fest */ type PositiveNumericStringGt<A extends string, B extends string> = A extends B ? false : [BuildTuple<StringLength<A>, 0>, BuildTuple<StringLength<B>, 0>] extends infer R extends [readonly unknown[], readonly unknown[]] ? R[0] extends [...R[1], ...infer Remain extends readonly unknown[]] ? 0 extends Remain["length"] ? SameLengthPositiveNumericStringGt<A, B> : true : false : never; /** Returns a boolean for whether `A` represents a number greater than `B`, where `A` and `B` are both positive numeric characters. @example ``` PositiveNumericCharacterGt<'5', '1'>; //=> true PositiveNumericCharacterGt<'1', '1'>; //=> false ``` */ type PositiveNumericCharacterGt<A extends string, B extends string> = NumericString extends `${infer HeadA}${A}${infer TailA}` ? NumericString extends `${infer HeadB}${B}${infer TailB}` ? HeadA extends `${HeadB}${infer _}${infer __}` ? true : false : never : never; //#endregion //#region ../core/src/types/type-fest/internal/numeric.d.ts /** Returns the absolute value of a given value. @example ``` NumberAbsolute<-1>; //=> 1 NumberAbsolute<1>; //=> 1 NumberAbsolute<NegativeInfinity> //=> PositiveInfinity ``` @group type-fest */ type NumberAbsolute<N extends number> = `${N}` extends `-${infer StringPositiveN}` ? StringToNumber<StringPositiveN> : N; //#endregion //#region ../core/src/types/type-fest/simplify.d.ts /** Useful to flatten the type output to improve type hints shown in editors. And also to transform an interface into a type to aide with assignability. @example ``` import type {Simplify} from 'type-fest'; type PositionProps = { top: number; left: number; }; type SizeProps = { width: number; height: number; }; // In your editor, hovering over `Props` will show a flattened object with all the properties. type Props = Simplify<PositionProps & SizeProps>; ``` Sometimes it is desired to pass a value as a function argument that has a different type. At first inspection it may seem assignable, and then you discover it is not because the `value`'s type definition was defined as an interface. In the following example, `fn` requires an argument of type `Record<string, unknown>`. If the value is defined as a literal, then it is assignable. And if the `value` is defined as type using the `Simplify` utility the value is assignable. But if the `value` is defined as an interface, it is not assignable because the interface is not sealed and elsewhere a non-string property could be added to the interface. If the type definition must be an interface (perhaps it was defined in a third-party npm package), then the `value` can be defined as `const value: Simplify<SomeInterface> = ...`. Then `value` will be assignable to the `fn` argument. Or the `value` can be cast as `Simplify<SomeInterface>` if you can't re-declare the `value`. @example ``` import type {Simplify} from 'type-fest'; interface SomeInterface { foo: number; bar?: string; baz: number | undefined; } type SomeType = { foo: number; bar?: string; baz: number | undefined; }; const literal = {foo: 123, bar: 'hello', baz: 456}; const someType: SomeType = literal; const someInterface: SomeInterface = literal; function fn(object: Record<string, unknown>): void {} fn(literal); // Good: literal object type is sealed fn(someType); // Good: type is sealed fn(someInterface); // Error: Index signature for type 'string' is missing in type 'someInterface'. Because `interface` can be re-opened fn(someInterface as Simplify<SomeInterface>); // Good: transform an `interface` into a `type` ``` @link https://github.com/microsoft/TypeScript/issues/15300 @see SimplifyDeep @group type-fest */ type Simplify<T> = { [KeyType in keyof T]: T[KeyType] } & {}; //#endregion //#region ../core/src/types/type-fest/union-to-intersection.d.ts /** Convert a union type to an intersection type using [distributive conditional types](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types). Inspired by [this Stack Overflow answer](https://stackoverflow.com/a/50375286/2172153). @example ``` import type {UnionToIntersection} from 'type-fest'; type Union = {the(): void} | {great(arg: string): void} | {escape: boolean}; type Intersection = UnionToIntersection<Union>; //=> {the(): void; great(arg: string): void; escape: boolean}; ``` A more applicable example which could make its way into your library code follows. @example ``` import type {UnionToIntersection} from 'type-fest'; class CommandOne { commands: { a1: () => undefined, b1: () => undefined, } } class CommandTwo { commands: { a2: (argA: string) => undefined, b2: (argB: string) => undefined, } } const union = [new CommandOne(), new CommandTwo()].map(instance => instance.commands); type Union = typeof union; //=> {a1(): void; b1(): void} | {a2(argA: string): void; b2(argB: string): void} type Intersection = UnionToIntersection<Union>; //=> {a1(): void; b1(): void; a2(argA: string): void; b2(argB: string): void} ``` @group type-fest */ type UnionToIntersection<Union> = (Union extends unknown ? (distributedUnion: Union) => void : never) extends ((mergedIntersection: infer Intersection) => void) ? Intersection & Union : never; //#endregion //#region ../core/src/types/type-fest/keys-of-union.d.ts /** Create a union of all keys from a given type, even those exclusive to specific union members. Unlike the native `keyof` keyword, which returns keys present in **all** union members, this type returns keys from **any** member. @link https://stackoverflow.com/a/49402091 @example ``` import type {KeysOfUnion} from 'type-fest'; type A = { common: string; a: number; }; type B = { common: string; b: string; }; type C = { common: string; c: boolean; }; type Union = A | B | C; type CommonKeys = keyof Union; //=> 'common' type AllKeys = KeysOfUnion<Union>; //=> 'common' | 'a' | 'b' | 'c' ``` @group type-fest */ type KeysOfUnion<ObjectType> = keyof UnionToIntersection<ObjectType extends unknown ? Record<keyof ObjectType, never> : never>; //#endregion //#region ../core/src/types/type-fest/optional-keys-of.d.ts /** Extract all optional keys from the given type. This is useful when you want to create a new type that contains different type values for the optional keys only. @example ``` import type {OptionalKeysOf, Except} from 'type-fest'; interface User { name: string; surname: string; luckyNumber?: number; } const REMOVE_FIELD = Symbol('remove field symbol'); type UpdateOperation<Entity extends object> = Except<Partial<Entity>, OptionalKeysOf<Entity>> & { [Key in OptionalKeysOf<Entity>]?: Entity[Key] | typeof REMOVE_FIELD; }; const update1: UpdateOperation<User> = { name: 'Alice' }; const update2: UpdateOperation<User> = { name: 'Bob', luckyNumber: REMOVE_FIELD }; ``` @group type-fest */ type OptionalKeysOf<BaseType extends object> = BaseType extends unknown ? (keyof { [Key in keyof BaseType as BaseType extends Record<Key, BaseType[Key]> ? never : Key]: never }) & (keyof BaseType) : never; //#endregion //#region ../core/src/types/type-fest/required-keys-of.d.ts /** Extract all required keys from the given type. This is useful when you want to create a new type that contains different type values for the required keys only or use the list of keys for validation purposes, etc... @example ``` import type {RequiredKeysOf} from 'type-fest'; declare function createValidation<Entity extends object, Key extends RequiredKeysOf<Entity> = RequiredKeysOf<Entity>>(field: Key, validator: (value: Entity[Key]) => boolean): ValidatorFn; interface User { name: string; surname: string; luckyNumber?: number; } const validator1 = createValidation<User>('name', value => value.length < 25); const validator2 = createValidation<User>('surname', value => value.length < 25); ``` @group type-fest */ type RequiredKeysOf<BaseType extends object> = BaseType extends unknown ? Exclude<keyof BaseType, OptionalKeysOf<BaseType>> : never; //#endregion //#region ../core/src/types/type-fest/omit-index-signature.d.ts /** Omit any index signatures from the given object type, leaving only explicitly defined properties. This is the counterpart of `PickIndexSignature`. Use-cases: - Remove overly permissive signatures from third-party types. This type was taken from this [StackOverflow answer](https://stackoverflow.com/a/68261113/420747). It relies on the fact that an empty object (`{}`) is assignable to an object with just an index signature, like `Record<string, unknown>`, but not to an object with explicitly defined keys, like `Record<'foo' | 'bar', unknown>`. (The actual value type, `unknown`, is irrelevant and could be any type. Only the key type matters.) ``` const indexed: Record<string, unknown> = {}; // Allowed const keyed: Record<'foo', unknown> = {}; // Error // => TS2739: Type '{}' is missing the following properties from type 'Record<"foo" | "bar", unknown>': foo, bar ``` Instead of causing a type error like the above, you can also use a [conditional type](https://www.typescriptlang.org/docs/handbook/2/conditional-types.html) to test whether a type is assignable to another: ``` type Indexed = {} extends Record<string, unknown> ? '✅ `{}` is assignable to `Record<string, unknown>`' : '❌ `{}` is NOT assignable to `Record<string, unknown>`'; // => '✅ `{}` is assignable to `Record<string, unknown>`' type Keyed = {} extends Record<'foo' | 'bar', unknown> ? "✅ `{}` is assignable to `Record<'foo' | 'bar', unknown>`" : "❌ `{}` is NOT assignable to `Record<'foo' | 'bar', unknown>`"; // => "❌ `{}` is NOT assignable to `Record<'foo' | 'bar', unknown>`" ``` Using a [mapped type](https://www.typescriptlang.org/docs/handbook/2/mapped-types.html#further-exploration), you can then check for each `KeyType` of `ObjectType`... ``` import type {OmitIndexSignature} from 'type-fest'; type OmitIndexSignature<ObjectType> = { [KeyType in keyof ObjectType // Map each key of `ObjectType`... ]: ObjectType[KeyType]; // ...to its original value, i.e. `OmitIndexSignature<Foo> == Foo`. }; ``` ...whether an empty object (`{}`) would be assignable to an object with that `KeyType` (`Record<KeyType, unknown>`)... ``` import type {OmitIndexSignature} from 'type-fest'; type OmitIndexSignature<ObjectType> = { [KeyType in keyof ObjectType // Is `{}` assignable to `Record<KeyType, unknown>`? as {} extends Record<KeyType, unknown> ? ... // ✅ `{}` is assignable to `Record<KeyType, unknown>` : ... // ❌ `{}` is NOT assignable to `Record<KeyType, unknown>` ]: ObjectType[KeyType]; }; ``` If `{}` is assignable, it means that `KeyType` is an index signature and we want to remove it. If it is not assignable, `KeyType` is a "real" key and we want to keep it. @example ``` import type {OmitIndexSignature} from 'type-fest'; interface Example { // These index signatures will be removed. [x: string]: any [x: number]: any [x: symbol]: any [x: `head-${string}`]: string [x: `${string}-tail`]: string [x: `head-${string}-tail`]: string [x: `${bigint}`]: string [x: `embedded-${number}`]: string // These explicitly defined keys will remain. foo: 'bar'; qux?: 'baz'; } type ExampleWithoutIndexSignatures = OmitIndexSignature<Example>; // => { foo: 'bar'; qux?: 'baz' | undefined; } ``` @see PickIndexSignature @group type-fest */ type OmitIndexSignature<ObjectType> = { [KeyType in keyof ObjectType as {} extends Record<KeyType, unknown> ? never : KeyType]: ObjectType[KeyType] }; //#endregion //#region ../core/src/types/type-fest/pick-index-signature.d.ts /** Pick only index signatures from the given object type, leaving out all explicitly defined properties. This is the counterpart of `OmitIndexSignature`. @example ``` import type {PickIndexSignature} from 'type-fest'; declare const symbolKey: unique symbol; type Example = { // These index signatures will remain. [x: string]: unknown; [x: number]: unknown; [x: symbol]: unknown; [x: `head-${string}`]: string; [x: `${string}-tail`]: string; [x: `head-${string}-tail`]: string; [x: `${bigint}`]: string; [x: `embedded-${number}`]: string; // These explicitly defined keys will be removed. ['kebab-case-key']: string; [symbolKey]: string; foo: 'bar'; qux?: 'baz'; }; type ExampleIndexSignature = PickIndexSignature<Example>; // { // [x: string]: unknown; // [x: number]: unknown; // [x: symbol]: unknown; // [x: `head-${string}`]: string; // [x: `${string}-tail`]: string; // [x: `head-${string}-tail`]: string; // [x: `${bigint}`]: string; // [x: `embedded-${number}`]: string; // } ``` @see OmitIndexSignature @group type-fest */ type PickIndexSignature<ObjectType> = { [KeyType in keyof ObjectType as {} extends Record<KeyType, unknown> ? KeyType : never]: ObjectType[KeyType] }; //#endregion //#region ../core/src/types/type-fest/merge.d.ts type SimpleMerge<Destination, Source> = { [Key in keyof Destination as Key extends keyof Source ? never : Key]: Destination[Key] } & Source; /** Merge two types into a new type. Keys of the second type overrides keys of the first type. @example ``` import type {Merge} from 'type-fest'; interface Foo { [x: string]: unknown; [x: number]: unknown; foo: string; bar: symbol; } type Bar = { [x: number]: number; [x: symbol]: unknown; bar: Date; baz: boolean; }; export type FooBar = Merge<Foo, Bar>; // => { // [x: string]: unknown; // [x: number]: number; // [x: symbol]: unknown; // foo: string; // bar: Date; // baz: boolean; // } ``` @group type-fest */ type Merge<Destination, Source> = Simplify<SimpleMerge<PickIndexSignature<Destination>, PickIndexSignature<Source>> & SimpleMerge<OmitIndexSignature<Destination>, OmitIndexSignature<Source>>>; //#endregion //#region ../core/src/types/type-fest/if-any.d.ts /** An if-else-like type that resolves depending on whether the given type is `any`. @see {@link IsAny} @example ``` import type {IfAny} from 'type-fest'; type ShouldBeTrue = IfAny<any>; //=> true type ShouldBeBar = IfAny<'not any', 'foo', 'bar'>; //=> 'bar' ``` @group type-fest */ type IfAny$1<T, TypeIfAny = true, TypeIfNotAny = false> = (IsAny<T> extends true ? TypeIfAny : TypeIfNotAny); //#endregion //#region ../core/src/types/type-fest/internal/type.d.ts /** Returns a boolean for whether the given `boolean` is not `false`. @group type-fest */ type IsNotFalse<T extends boolean> = [T] extends [false] ? false : true; /** Returns a boolean for whether the given type is primitive value or primitive type. @example ``` IsPrimitive<'string'> //=> true IsPrimitive<string> //=> true IsPrimitive<Object> //=> false ``` @group type-fest */ type IsPrimitive<T> = [T] extends [Primitive] ? true : false; /** Returns a boolean for whether A is false. @example ``` Not<true>; //=> false Not<false>; //=> true ``` @group type-fest */ type Not<A extends boolean> = A extends true ? false : A extends false ? true : never; /** An if-else-like type that resolves depending on whether the given type is `any` or `never`. @example ``` // When `T` is a NOT `any` or `never` (like `string`) => Returns `IfNotAnyOrNever` branch type A = IfNotAnyOrNever<string, 'VALID', 'IS_ANY', 'IS_NEVER'>; //=> 'VALID' // When `T` is `any` => Returns `IfAny` branch type B = IfNotAnyOrNever<any, 'VALID', 'IS_ANY', 'IS_NEVER'>; //=> 'IS_ANY' // When `T` is `never` => Returns `IfNever` branch type C = IfNotAnyOrNever<never, 'VALID', 'IS_ANY', 'IS_NEVER'>; //=> 'IS_NEVER' ``` @group type-fest */ type IfNotAnyOrNever<T, IfNotAnyOrNever, IfAny = any, IfNever = never> = IsAny<T> extends true ? IfAny : IsNever<T> extends true ? IfNever : IfNotAnyOrNever; //#endregion //#region ../core/src/types/type-fest/internal/object.d.ts /** Works similar to the built-in `Pick` utility type, except for the following differences: - Distributes over union types and allows picking keys from any member of the union type. - Primitives types are returned as-is. - Picks all keys if `Keys` is `any`. - Doesn't pick `number` from a `string` index signature. @example ``` type ImageUpload = { url: string; size: number; thumbnailUrl: string; }; type VideoUpload = { url: string; duration: number; encodingFormat: string; }; // Distributes over union types and allows picking keys from any member of the union type type MediaDisplay = HomomorphicPick<ImageUpload | VideoUpload, "url" | "size" | "duration">; //=> {url: string; size: number} | {url: string; duration: number} // Primitive types are returned as-is type Primitive = HomomorphicPick<string | number, 'toUpperCase' | 'toString'>; //=> string | number // Picks all keys if `Keys` is `any` type Any = HomomorphicPick<{a: 1; b: 2} | {c: 3}, any>; //=> {a: 1; b: 2} | {c: 3} // Doesn't pick `number` from a `string` index signature type IndexSignature = HomomorphicPick<{[k: string]: unknown}, number>; //=> {} @group type-fest */ type HomomorphicPick<T, Keys extends KeysOfUnion<T>> = { [P in keyof T as Extract<P, Keys>]: T[P] }; /** Merges user specified options with default options. @example ``` type PathsOptions = {maxRecursionDepth?: number; leavesOnly?: boolean}; type DefaultPathsOptions = {maxRecursionDepth: 10; leavesOnly: false}; type SpecifiedOptions = {leavesOnly: true}; type Result = ApplyDefaultOptions<PathsOptions, DefaultPathsOptions, SpecifiedOptions>; //=> {maxRecursionDepth: 10; leavesOnly: true} ``` @example ``` // Complains if default values are not provided for optional options type PathsOptions = {maxRecursionDepth?: number; leavesOnly?: boolean}; type DefaultPathsOptions = {maxRecursionDepth: 10}; type SpecifiedOptions = {}; type Result = ApplyDefaultOptions<PathsOptions, DefaultPathsOptions, SpecifiedOptions>; // ~~~~~~~~~~~~~~~~~~~ // Property 'leavesOnly' is missing in type 'DefaultPathsOptions' but required in type '{ maxRecursionDepth: number; leavesOnly: boolean; }'. ``` @example ``` // Complains if an option's default type does not conform to the expected type type PathsOptions = {maxRecursionDepth?: number; leavesOnly?: boolean}; type DefaultPathsOptions = {maxRecursionDepth: 10; leavesOnly: 'no'}; type SpecifiedOptions = {}; type Result = ApplyDefaultOptions<PathsOptions, DefaultPathsOptions, SpecifiedOptions>; // ~~~~~~~~~~~~~~~~~~~ // Types of property 'leavesOnly' are incompatible. Type 'string' is not assignable to type 'boolean'. ``` @example ``` // Complains if an option's specified type does not conform to the expected type type PathsOptions = {maxRecursionDepth?: number; leavesOnly?: boolean}; type DefaultPathsOptions = {maxRecursionDepth: 10; leavesOnly: false}; type SpecifiedOptions = {leavesOnly: 'yes'}; type Result = ApplyDefaultOptions<PathsOptions, DefaultPathsOptions, SpecifiedOptions>; // ~~~~~~~~~~~~~~~~ // Types of property 'leavesOnly' are incompatible. Type 'string' is not assignable to type 'boolean'. ``` @group type-fest */ type ApplyDefaultOptions<Options extends object, Defaults extends Simplify<Omit<Required<Options>, RequiredKeysOf<Options>> & Partial<Record<RequiredKeysOf<Options>, never>>>, SpecifiedOptions extends Options> = IfAny$1<SpecifiedOptions, Defaults, IfNever$1<SpecifiedOptions, Defaults, Simplify<Merge<Defaults, { [Key in keyof SpecifiedOptions as Key extends OptionalKeysOf<Options> ? Extract<SpecifiedOptions[Key], undefined> extends never ? Key : never : Key]: SpecifiedOptions[Key] }> & Required<Options>>>>; //#endregion //#region ../core/src/types/type-fest/except.d.ts /** Filter out keys from an object. Returns `never` if `Exclude` is strictly equal to `Key`. Returns `never` if `Key` extends `Exclude`. Returns `Key` otherwise. @example ``` type Filtered = Filter<'foo', 'foo'>; //=> never ``` @example ``` type Filtered = Filter<'bar', string>; //=> never ``` @example ``` type Filtered = Filter<'bar', 'foo'>; //=> 'bar' ``` @see {Except} */ type Filter<KeyType, ExcludeType> = IsEqual<KeyType, ExcludeType> extends true ? never : (KeyType extends ExcludeType ? never : KeyType); type ExceptOptions = { /** Disallow assigning non-specified properties. Note that any omitted properties in the resulting type will be present in autocomplete as `undefined`. @default false */ requireExactProps?: boolean; }; type DefaultExceptOptions = { requireExactProps: false; }; /** Create a type from an object type without certain keys. We recommend setting the `requireExactProps` option to `true`. This type is a stricter version of [`Omit`](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-5.html#the-omit-helper-type). The `Omit` type does not restrict the omitted keys to be keys present on the given type, while `Except` does. The benefits of a stricter type are avoiding typos and allowing the compiler to pick up on rename refactors automatically. This type was proposed to the TypeScript team, which declined it, saying they prefer that libraries implement stricter versions of the built-in types ([microsoft/TypeScript#30825](https://github.com/microsoft/TypeScript/issues/30825#issuecomment-523668235)). @example ``` import type {Except} from 'type-fest'; type Foo = { a: number; b: string; }; type FooWithoutA = Except<Foo, 'a'>; //=> {b: string} const fooWithoutA: FooWithoutA = {a: 1, b: '2'}; //=> errors: 'a' does not exist in type '{ b: string; }' type FooWithoutB = Except<Foo, 'b', {requireExactProps: true}>; //=> {a: number} & Partial<Record<"b", never>> const fooWithoutB: FooWithoutB = {a: 1, b: '2'}; //=> errors at 'b': Type 'string' is not assignable to type 'undefined'. // The `Omit` utility type doesn't work when omitting specific keys from objects containing index signatures. // Consider the following example: type UserData = { [metadata: string]: string; email: string; name: string; role: 'admin' | 'user'; }; // `Omit` clearly doesn't behave as expected in this case: type PostPayload = Omit<UserData, 'email'>; //=> type PostPayload = { [x: string]: string; [x: number]: string; } // In situations like this, `Except` works better. // It simply removes the `email` key while preserving all the other keys. type PostPayload = Except<UserData, 'email'>; //=> type PostPayload = { [x: string]: string; name: string; role: 'admin' | 'user'; } ``` @group type-fest */ type Except<ObjectType, KeysType extends keyof ObjectType, Options extends ExceptOptions = {}> = _Except<ObjectType, KeysType, ApplyDefaultOptions<ExceptOptions, DefaultExceptOptions, Options>>; type _Except<ObjectType, KeysType extends keyof ObjectType, Options extends Required<ExceptOptions>> = { [KeyType in keyof ObjectType as Filter<KeyType, KeysType>]: ObjectType[KeyType] } & (Options["requireExactProps"] extends true ? Partial<Record<KeysType, never>> : {}); //#endregion //#region ../core/src/types/type-fest/override-properties.d.ts /** Override existing properties of the given type. Similar to `Merge`, but enforces that the original type has the properties you want to override. This is useful when you want to override existing properties with a different type and make sure that these properties really exist in the original. @example ``` type Foo = { a: string b: string } type Bar = OverrideProperties<Foo, {b: number}> //=> {a: string, b: number} type Baz = OverrideProperties<Foo, {c: number}> // Error, type '{ c: number; }' does not satisfy the constraint '{ c: never; }' type Fizz = OverrideProperties<Foo, {b: number; c: number}> // Error, type '{ b: number; c: number; }' does not satisfy the constraint '{ b: number; c: never; }' ``` @group type-fest */ type OverrideProperties<TOriginal, TOverride extends Partial<Record<keyof TOriginal, unknown>> & { [Key in keyof TOverride]: Key extends keyof TOriginal ? TOverride[Key] : never }> =