type-fest
Advanced tools
Comparing version 4.12.0 to 4.13.0
@@ -9,2 +9,3 @@ // Basic | ||
export type {KeysOfUnion} from './source/keys-of-union'; | ||
export type {DistributedOmit} from './source/distributed-omit'; | ||
export type {EmptyObject, IsEmptyObject} from './source/empty-object'; | ||
@@ -11,0 +12,0 @@ export type {NonEmptyObject} from './source/non-empty-object'; |
{ | ||
"name": "type-fest", | ||
"version": "4.12.0", | ||
"version": "4.13.0", | ||
"description": "A collection of essential TypeScript types", | ||
@@ -5,0 +5,0 @@ "license": "(MIT OR CC0-1.0)", |
@@ -185,2 +185,3 @@ <div align="center"> | ||
- [`SharedUnionFieldsDeep`](source/shared-union-fields-deep.d.ts) - Create a type with shared fields from a union of object types, deeply traversing nested structures. | ||
- [`DistributedOmit`](source/distributed-omit.d.ts) - Omits keys from a type, distributing the operation over a union. | ||
@@ -327,2 +328,3 @@ ### Type Guard | ||
- `AllKeys` - See [`KeysOfUnion`](source/keys-of-union.d.ts) | ||
- `Branded` - See [`Opaque`](source/opaque.d.ts) | ||
@@ -329,0 +331,0 @@ ## Tips |
import type {Sum} from './sum'; | ||
import type {LessThan} from './less-than'; | ||
import type {LessThanOrEqual} from './less-than-or-equal'; | ||
import type {GreaterThanOrEqual} from './greater-than-or-equal'; | ||
import type {GreaterThan} from './greater-than'; | ||
import type {IsNegative} from './numeric'; | ||
import type {And} from './internal'; | ||
import type {And, Not, ArrayMin} from './internal'; | ||
import type {IsEqual} from './is-equal'; | ||
import type {ArraySplice} from './array-splice'; | ||
@@ -57,6 +59,23 @@ /** | ||
Array_ extends readonly unknown[], | ||
Start extends number = 0, | ||
End extends number = Array_['length'], | ||
> = ArraySliceHelper<Array_, Start, End>; | ||
Start extends number = never, | ||
End extends number = never, | ||
> = And<IsEqual<Start, never>, IsEqual<End, never>> extends true | ||
? Array_ | ||
: number extends Array_['length'] | ||
? VariableLengthArraySliceHelper<Array_, Start, End> | ||
: ArraySliceHelper<Array_, IsEqual<Start, never> extends true ? 0 : Start, IsEqual<End, never> extends true ? Array_['length'] : End>; | ||
type VariableLengthArraySliceHelper< | ||
Array_ extends readonly unknown[], | ||
Start extends number, | ||
End extends number, | ||
> = And<Not<IsNegative<Start>>, IsEqual<End, never>> extends true | ||
? ArraySplice<Array_, 0, Start> | ||
: And< | ||
And<Not<IsNegative<Start>>, Not<IsNegative<End>>>, | ||
IsEqual<GreaterThan<End, Start>, true> | ||
> extends true | ||
? ArraySliceByPositiveIndex<Array_, Start, End> | ||
: []; | ||
type ArraySliceHelper< | ||
@@ -77,5 +96,5 @@ Array_ extends readonly unknown[], | ||
PositiveE extends number = IsNegative<End> extends true ? Sum<ArrayLength, End> : End, | ||
> = true extends [IsNegative<PositiveS>, LessThanOrEqual<PositiveE, PositiveS>][number] | ||
> = true extends [IsNegative<PositiveS>, LessThanOrEqual<PositiveE, PositiveS>, GreaterThanOrEqual<PositiveS, ArrayLength>][number] | ||
? [] | ||
: ArraySliceByPositiveIndex<Array_, PositiveS, PositiveE>; | ||
: ArraySliceByPositiveIndex<Array_, ArrayMin<[PositiveS, ArrayLength]>, ArrayMin<[PositiveE, ArrayLength]>>; | ||
@@ -86,11 +105,5 @@ type ArraySliceByPositiveIndex< | ||
End extends number, | ||
TraversedElement extends Array<Array_[number]> = [], | ||
Result extends Array<Array_[number]> = [], | ||
> = Array_ extends readonly [infer H, ...infer Rest] | ||
? And< | ||
IsEqual<LessThanOrEqual<Start, TraversedElement['length']>, true>, | ||
IsEqual<LessThan<TraversedElement['length'], End>, true> | ||
> extends true | ||
? ArraySliceByPositiveIndex<Rest, Start, End, [...TraversedElement, H], [...Result, H]> | ||
: ArraySliceByPositiveIndex<Rest, Start, End, [...TraversedElement, H], Result> | ||
: Result; | ||
> = Start extends End | ||
? Result | ||
: ArraySliceByPositiveIndex<Array_, Sum<Start, 1>, End, [...Result, Array_[Start]]>; |
import type {ArraySplice} from './array-splice'; | ||
import type {ExactKey, IsArrayReadonly, NonRecursiveType, SetArrayAccess, ToString} from './internal'; | ||
import type {IsEqual} from './is-equal'; | ||
import type {IsNever} from './is-never'; | ||
import type {LiteralUnion} from './literal-union'; | ||
import type {SimplifyDeep} from './merge-deep'; | ||
@@ -72,3 +74,3 @@ import type {Paths} from './paths'; | ||
*/ | ||
export type OmitDeep<T, PathUnion extends Paths<T>> = | ||
export type OmitDeep<T, PathUnion extends LiteralUnion<Paths<T>, string>> = | ||
SimplifyDeep< | ||
@@ -106,5 +108,7 @@ SharedUnionFieldsDeep< | ||
: ExactKey<ObjectT, P> extends infer Key | ||
? Key extends PropertyKey | ||
? Omit<ObjectT, Key> | ||
: ObjectT | ||
? IsNever<Key> extends true | ||
? ObjectT | ||
: Key extends PropertyKey | ||
? Omit<ObjectT, Key> | ||
: ObjectT | ||
: ObjectT; | ||
@@ -138,2 +142,2 @@ | ||
: ArraySplice<ArrayType, ArrayIndex, 1, [unknown]> | ||
: never; | ||
: ArrayType; |
import type {IsUnknown} from './is-unknown'; | ||
import type {StaticPartOfArray} from './internal'; | ||
import type {UnknownArray} from './unknown-array'; | ||
/** | ||
Create a tuple that replaces the given `Tuple`'s elements with the given `Record_`'s values at the given indices. | ||
Create an array that replaces the given `TArray`'s elements with the given `TObject`'s values at the given indices. | ||
`TArray` and `TObject` supports tailing spread array like `[string, ...boolean[]]`, but does not support `[string, ...boolean[], number]`. | ||
@example: | ||
```ts | ||
// object | ||
type A = MergeObjectToArray<[string, number], {0: boolean}>; | ||
//=> [boolean, number] | ||
// array | ||
type B = MergeObjectToArray<[string, number], [boolean]>; | ||
//=> [boolean, number] | ||
// tailing spread array | ||
type C = MergeObjectToArray<[string, ...boolean[]], {1: number}>; | ||
//=> [string, ...number[]] | ||
type D = MergeObjectToArray<[string, ...boolean[]], [number, ...string[]]>; | ||
//=> [number, ...string[]] | ||
``` | ||
*/ | ||
type MergeObjectToTuple<Tuple extends unknown[], Record_ extends Record<number, unknown>> = { | ||
[K in keyof Tuple]: Record_ extends Record<string, unknown> | ||
// Handle object case like `{0: string, 1: number}` | ||
? K extends `${infer NumberK extends number}` | ||
? NumberK extends keyof Record_ ? Record_[K] : Tuple[K] | ||
: never // Should not happen | ||
// Handle tuple case like `[string, number]` | ||
: K extends keyof Record_ ? Record_[K] : Tuple[K] | ||
}; | ||
type MergeObjectToArray<TArray extends UnknownArray, TObject, TArrayCopy extends UnknownArray = TArray> = | ||
// If `TObject` is an array like `[0, 1, 2]` | ||
TObject extends UnknownArray | ||
// If `TObject` is a variable length array, we should use `TObject`'s type as the result type. | ||
? number extends TObject['length'] | ||
? TObject | ||
: { | ||
[K in keyof TArray]: K extends keyof TObject ? TObject[K] : TArray[K] | ||
} | ||
: TObject extends object | ||
// If `TObject` is a object witch key is number like `{0: string, 1: number}` | ||
? { | ||
[K in keyof TArray]: | ||
K extends `${infer NumberK extends number}` | ||
? NumberK extends keyof TObject ? TObject[NumberK] : TArray[K] | ||
: number extends K | ||
// If array key `K` is `number`, means it's a rest parameter, we should set the rest parameter type to corresponding type in `TObject`. | ||
// example: `MergeObjectToParamterArray<[string, ...boolean[]], {1: number}>` => `[string, ...number[]]` | ||
? StaticPartOfArray<TArrayCopy>['length'] extends keyof TObject | ||
? TObject[StaticPartOfArray<TArrayCopy>['length']] | ||
: TArray[K] | ||
: never | ||
} : never; | ||
@@ -42,3 +78,3 @@ /** | ||
type HandleMessage = (data: Data, message: string) => void; | ||
type HandleMessage = (data: Data, message: string, ...arguments: any[]) => void; | ||
@@ -52,5 +88,15 @@ type HandleOk = SetParameterType<HandleMessage, {0: SuccessData, 1: 'ok'}>; | ||
// Could change single parameter type. | ||
// Change single parameter type. | ||
type HandleWarn = SetParameterType<HandleMessage, {1: 'warn'}>; | ||
//=> type HandleWarn = (data: Data, message: 'warn') => void; | ||
// Change rest parameter type. | ||
// Way 1: Input full parameter type. | ||
type HandleLog = SetParameterType<HandleMessage, [data: Data, message: 'log', ...arguments: string[]]>; | ||
//=> type HandleLog = (data: Data, message: 'log', ...arguments: string[]) => void; | ||
// Way 2: Input rest parameter type by Object index. | ||
type HandleLog2 = SetParameterType<HandleMessage, {2: string}>; | ||
//=> type HandleLog2 = (data: Data, message: string, ...arguments: string[]) => void; | ||
``` | ||
@@ -67,5 +113,5 @@ | ||
IsUnknown<ThisArg> extends true | ||
? (...arguments_: MergeObjectToTuple<Arguments, P>) => ReturnType<Fn> | ||
: (this: ThisArg, ...arguments_: MergeObjectToTuple<Arguments, P>) => ReturnType<Fn> | ||
? (...arguments_: MergeObjectToArray<Arguments, P>) => ReturnType<Fn> | ||
: (this: ThisArg, ...arguments_: MergeObjectToArray<Arguments, P>) => ReturnType<Fn> | ||
) | ||
: Fn; // This part should be unreachable |
@@ -37,31 +37,33 @@ import type {NumberAbsolute, BuildTuple, And, Or} from './internal'; | ||
// TODO: Support big integer and negative number. | ||
export type Subtract<A extends number, B extends number> = [ | ||
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 | ||
? PositiveInfinity | ||
: Or< | ||
And<IsEqual<R[1], true>, IsEqual<R[3], false>>, | ||
And<IsEqual<R[2], true>, IsEqual<R[0], false>> | ||
export type Subtract<A extends number, B extends number> = number extends A | B | ||
? number | ||
: [ | ||
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 | ||
? NegativeInfinity | ||
: true extends R[number] | ||
? number | ||
: [IsNegative<A>, IsNegative<B>] extends infer R | ||
? [false, false] extends R | ||
? BuildTuple<A> extends infer R | ||
? R extends [...BuildTuple<B>, ...infer R] | ||
? R['length'] | ||
: number | ||
: never | ||
: LessThan<A, B> extends true | ||
? number | ||
: [false, true] extends R | ||
? Sum<A, NumberAbsolute<B>> | ||
: Subtract<NumberAbsolute<B>, NumberAbsolute<A>> | ||
: never | ||
: never; | ||
? PositiveInfinity | ||
: Or< | ||
And<IsEqual<R[1], true>, IsEqual<R[3], false>>, | ||
And<IsEqual<R[2], true>, IsEqual<R[0], false>> | ||
> extends true | ||
? NegativeInfinity | ||
: true extends R[number] | ||
? number | ||
: [IsNegative<A>, IsNegative<B>] extends infer R | ||
? [false, false] extends R | ||
? BuildTuple<A> extends infer R | ||
? R extends [...BuildTuple<B>, ...infer R] | ||
? R['length'] | ||
: number | ||
: never | ||
: LessThan<A, B> extends true | ||
? number | ||
: [false, true] extends R | ||
? Sum<A, NumberAbsolute<B>> | ||
: Subtract<NumberAbsolute<B>, NumberAbsolute<A>> | ||
: never | ||
: never; |
@@ -37,31 +37,33 @@ import type {NumberAbsolute, BuildTuple, And, Or, ArrayMax, ArrayMin} from './internal'; | ||
// TODO: Support big integer and negative number. | ||
export type Sum<A extends number, B extends number> = [ | ||
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[3], false>>, | ||
And<IsEqual<R[2], true>, IsEqual<R[1], false>> | ||
> extends true | ||
? PositiveInfinity | ||
: Or< | ||
And<IsEqual<R[1], true>, IsEqual<R[2], false>>, | ||
And<IsEqual<R[3], true>, IsEqual<R[0], false>> | ||
export type Sum<A extends number, B extends number> = number extends A | B | ||
? number | ||
: [ | ||
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[3], false>>, | ||
And<IsEqual<R[2], true>, IsEqual<R[1], false>> | ||
> extends true | ||
? NegativeInfinity | ||
: true extends R[number] | ||
? number | ||
: ([IsNegative<A>, IsNegative<B>] extends infer R | ||
? [false, false] extends R | ||
? [...BuildTuple<A>, ...BuildTuple<B>]['length'] | ||
: [true, true] extends R | ||
? number | ||
: ArrayMax<[NumberAbsolute<A>, NumberAbsolute<B>]> extends infer Max_ | ||
? ArrayMin<[NumberAbsolute<A>, NumberAbsolute<B>]> extends infer Min_ extends number | ||
? Max_ extends A | B | ||
? Subtract<Max_, Min_> | ||
: number | ||
? PositiveInfinity | ||
: Or< | ||
And<IsEqual<R[1], true>, IsEqual<R[2], false>>, | ||
And<IsEqual<R[3], true>, IsEqual<R[0], false>> | ||
> extends true | ||
? NegativeInfinity | ||
: true extends R[number] | ||
? number | ||
: ([IsNegative<A>, IsNegative<B>] extends infer R | ||
? [false, false] extends R | ||
? [...BuildTuple<A>, ...BuildTuple<B>]['length'] | ||
: [true, true] extends R | ||
? number | ||
: ArrayMax<[NumberAbsolute<A>, NumberAbsolute<B>]> extends infer Max_ | ||
? ArrayMin<[NumberAbsolute<A>, NumberAbsolute<B>]> extends infer Min_ extends number | ||
? Max_ extends A | B | ||
? Subtract<Max_, Min_> | ||
: number | ||
: never | ||
: never | ||
: never | ||
: never) & number | ||
: never; | ||
: never) & number | ||
: never; |
353468
132
8490
970