diff --git a/packages/ts-type-utils/src/index-of-tuple.d.mts b/packages/ts-type-utils/src/index-of-tuple.d.mts index e0f55ccc32..0a67a04ebe 100644 --- a/packages/ts-type-utils/src/index-of-tuple.d.mts +++ b/packages/ts-type-utils/src/index-of-tuple.d.mts @@ -13,13 +13,11 @@ declare namespace TSTypeUtilsInternals { : number; } -// type IndexOfTuple = TypeEq< -// T, -// readonly [] -// > extends true -// ? never -// : TypeEq extends true -// ? never -// : IsFixedLengthList extends true -// ? Exclude>['length'], undefined> -// : SafeUint; +// type IndexOfTuple = +// TypeEq extends true +// ? never +// : TypeEq extends true +// ? never +// : IsFixedLengthList extends true +// ? Exclude>['length'], undefined> +// : SafeUint; diff --git a/packages/ts-type-utils/src/index-type.d.mts b/packages/ts-type-utils/src/index-type.d.mts index 7fdfc16cfa..c0e78dce44 100644 --- a/packages/ts-type-utils/src/index-type.d.mts +++ b/packages/ts-type-utils/src/index-type.d.mts @@ -1,7 +1,9 @@ type Index = IndexOfTuple>; +type IndexInclusive = IndexOfTuple<[...MakeTuple<0, N>, 0]>; + type NegativeIndex = TSTypeUtilsInternals.MapIdx< - RelaxedExclude]>, 0> + RelaxedExclude, 0> >; /** @internal */ diff --git a/packages/ts-type-utils/src/max.d.mts b/packages/ts-type-utils/src/max.d.mts index 04cc13016c..7d5b66aa2d 100644 --- a/packages/ts-type-utils/src/max.d.mts +++ b/packages/ts-type-utils/src/max.d.mts @@ -10,32 +10,32 @@ declare namespace TSTypeUtilsInternals { : MaxImpl; } -// namespace _MaxImpl { -// /** -// * LEQ[3 | 5] == 0 | 1 | 2 | 3 | 4 | 5; -// */ +// declare namespace TSTypeUtilsInternals { +// /** `LEQ[3 | 5] == 0 | 1 | 2 | 3 | 4 | 5;` */ // type LEQ = { // [N in Index<64>]: IndexOfTuple<[0, ...MakeTuple<0, N>]>; // }; -// /** -// * @returns Y if A == B otherwise N -// */ +// /** @returns Y if A == B otherwise N */ // type Eq = [A] extends [B] ? ([B] extends [A] ? Y : N) : N; +// type ToLEQ = { +// [K in keyof LEQ]: [N] extends [RelaxedExclude] ? never : K; +// }[keyof LEQ]; + // /** // * The former part // * // * ```ts // * type Main< // * N extends number, -// * U extends number = ToLEQ> +// * U extends number = ToLEQ>, // * > = { // * [K in keyof LEQ]: Eq; -// * } +// * }; // * ``` // * -// * behaves like this +// * Behaves like this // * // * ```ts // * type R = { @@ -50,21 +50,16 @@ declare namespace TSTypeUtilsInternals { // * } // * ``` // */ -// type Main< -// N extends number, -// U extends number = LEQ[Extract] -// > = { +// type Main> = { // [K in keyof LEQ]: Eq; // }[keyof LEQ]; -// } -// type Max = _MaxImpl.Main; - -// type _MaxImpl, T extends readonly unknown[]> = { -// b: T['length']; -// r: _MaxImpl; -// }[[N] extends [Partial['length']] ? 'b' : 'r']; +// // type MaxImpl, T extends readonly unknown[]> = { +// // b: T['length']; +// // r: MaxImpl; +// // }[[N] extends [Partial['length']] ? 'b' : 'r']; +// } -// type Max> = _MaxImpl; +// type Max = TSTypeUtilsInternals.Main; // https://stackoverflow.com/questions/62968955/how-to-implement-a-type-level-max-function-over-a-union-of-literals-in-typescri diff --git a/packages/ts-type-utils/src/min.d.mts b/packages/ts-type-utils/src/min.d.mts index bf5537aa9b..2f8eaed186 100644 --- a/packages/ts-type-utils/src/min.d.mts +++ b/packages/ts-type-utils/src/min.d.mts @@ -10,13 +10,11 @@ declare namespace TSTypeUtilsInternals { : MinImpl; } -// type _MinImpl< -// N extends Index<64>, -// Count extends number -// > = IsNever extends true -// ? never -// : 0 extends N -// ? Count -// : _MinImpl, Increment & number>; - // type Min> = _MinImpl; +// +// type MinImpl, Count extends number> = +// IsNever extends true +// ? never +// : 0 extends N +// ? Count +// : _MinImpl, Increment & number>; diff --git a/packages/ts-type-utils/src/to-number.d.mts b/packages/ts-type-utils/src/to-number.d.mts index 7ebac8cdbe..89ec74a163 100644 --- a/packages/ts-type-utils/src/to-number.d.mts +++ b/packages/ts-type-utils/src/to-number.d.mts @@ -2,30 +2,36 @@ type ToNumber = S extends `${infer N extends number}` ? N : never; +/* TypeScript v4.8 以前では以下の実装が必要 */ + // type ToNumber = -// _ToNumberInternals._IsSmallNumber extends true -// ? _MakeTupleInternals.MakeTupleImpl['length'] +// TSTypeUtilsInternals._IsSmallNumber extends true +// ? TSTypeUtilsInternals.MakeTupleInternals.MakeTupleImpl< +// unknown, +// S, +// [] +// >['length'] // : S; -// namespace _ToNumberInternals { +// declare namespace TSTypeUtilsInternals { // // config -// type _DigitUpperLimit = 4; +// type DigitUpperLimit = 4; -// type _IsSmallNumber = _IsSmallNumberImpl< +// type IsSmallNumber = IsSmallNumberImpl< // S, -// MakeTuple +// MakeTuple // >; -// type _Digit = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9; +// type Digit = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9; -// type _Tail = T extends `${_Digit}${infer U}` ? U : never; +// type Tail = T extends `${Digit}${infer U}` ? U : never; -// type _IsSmallNumberImpl< +// type IsSmallNumberImpl< // S extends string, -// Counter extends readonly unknown[] +// Counter extends readonly unknown[], // > = S extends '' // ? true // : TypeEq extends true -// ? false // reached the limit -// : _IsSmallNumberImpl<_Tail, Tuple.Tail>; +// ? false // reached the limit +// : IsSmallNumberImpl, Tuple.Tail>; // } diff --git a/packages/ts-type-utils/src/uint-range.d.mts b/packages/ts-type-utils/src/uint-range.d.mts index 71ecb955c1..98090e640d 100644 --- a/packages/ts-type-utils/src/uint-range.d.mts +++ b/packages/ts-type-utils/src/uint-range.d.mts @@ -3,8 +3,6 @@ type UintRange = RelaxedExclude< Index >; -type IndexInclusive = IndexOfTuple<[...MakeTuple<0, N>, 0]>; - type UintRangeInclusive< MinValue extends number, MaxValue extends number, diff --git a/packages/ts-type-utils/src/utils.d.mts b/packages/ts-type-utils/src/utils.d.mts index 6047cbb995..1431d023db 100644 --- a/packages/ts-type-utils/src/utils.d.mts +++ b/packages/ts-type-utils/src/utils.d.mts @@ -10,14 +10,17 @@ type TypeEq = type TypeExtends = A extends B ? true : false; +/** Extract from T those types that are assignable to U */ +type RelaxedExtract = T extends U ? T : never; + +/** From T, pick a set of properties whose keys are in the union K */ +type RelaxedPick = Pick>; + /** Exclude from T those types that are assignable to U */ type RelaxedExclude = T extends U ? never : T; /** Construct a type with the properties of T except for those in type K. */ -type RelaxedOmit = Pick< - T, - RelaxedExclude ->; +type RelaxedOmit = Pick>; /* type constants */ @@ -154,41 +157,15 @@ type MutableArrayOfLength = Mutable< // https://qiita.com/uhyo/items/80ce7c00f413c1d1be56 -type MutableArrayOfLengthOrMore = MutableArrayAtLeastLen< - N, - Elm ->; type MutableArrayAtLeastLen = Mutable< ArrayAtLeastLen >; -type ArrayOfLengthOrMore = ArrayAtLeastLen; type ArrayAtLeastLen = readonly [ ...MakeTuple, ...Elm[], ]; -// type ArrayAtLeastLen = ArrayAtLeastLenRec< -// N, -// Elm, -// Elm[], -// [] -// >; - -// type ArrayAtLeastLenRec< -// Num, -// Elm, -// T extends readonly unknown[], -// C extends readonly unknown[], -// > = C extends { length: Num } -// ? T -// : ArrayAtLeastLenRec< -// Num, -// Elm, -// readonly [Elm, ...T], -// readonly [unknown, ...C] -// >; - type MergeIntersection = { [K in keyof R]: R[K]; }; diff --git a/packages/ts-type-utils/test/array-of-length.mts b/packages/ts-type-utils/test/array-of-length.mts index 2599c75cb2..00ef086b39 100644 --- a/packages/ts-type-utils/test/array-of-length.mts +++ b/packages/ts-type-utils/test/array-of-length.mts @@ -14,6 +14,6 @@ expectType, readonly [0, 0, 0]>('='); expectType, readonly [1, 1, 1, 1]>('='); expectType, [1, 1, 1, 1]>('='); -expectType, readonly 0[]>('='); -expectType, readonly [0, 0, 0, ...0[]]>('='); -expectType, readonly [1, 1, 1, 1, ...1[]]>('='); +expectType, readonly 0[]>('='); +expectType, readonly [0, 0, 0, ...0[]]>('='); +expectType, readonly [1, 1, 1, 1, ...1[]]>('=');