Skip to content

Commit

Permalink
feat: update ts-type-utils (#1445)
Browse files Browse the repository at this point in the history
  • Loading branch information
noshiro-pf authored Mar 2, 2025
1 parent 83752a9 commit 44fddde
Show file tree
Hide file tree
Showing 8 changed files with 63 additions and 89 deletions.
18 changes: 8 additions & 10 deletions packages/ts-type-utils/src/index-of-tuple.d.mts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,11 @@ declare namespace TSTypeUtilsInternals {
: number;
}

// type IndexOfTuple<T extends readonly unknown[]> = TypeEq<
// T,
// readonly []
// > extends true
// ? never
// : TypeEq<T, []> extends true
// ? never
// : IsFixedLengthList<T> extends true
// ? Exclude<Partial<ListType.ButLast<T>>['length'], undefined>
// : SafeUint;
// type IndexOfTuple<T extends readonly unknown[]> =
// TypeEq<T, readonly []> extends true
// ? never
// : TypeEq<T, []> extends true
// ? never
// : IsFixedLengthList<T> extends true
// ? Exclude<Partial<ListType.ButLast<T>>['length'], undefined>
// : SafeUint;
4 changes: 3 additions & 1 deletion packages/ts-type-utils/src/index-type.d.mts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
type Index<N extends number> = IndexOfTuple<MakeTuple<0, N>>;

type IndexInclusive<N extends number> = IndexOfTuple<[...MakeTuple<0, N>, 0]>;

type NegativeIndex<N extends number> = TSTypeUtilsInternals.MapIdx<
RelaxedExclude<IndexOfTuple<[0, ...MakeTuple<0, N>]>, 0>
RelaxedExclude<IndexInclusive<N>, 0>
>;

/** @internal */
Expand Down
39 changes: 17 additions & 22 deletions packages/ts-type-utils/src/max.d.mts
Original file line number Diff line number Diff line change
Expand Up @@ -10,32 +10,32 @@ declare namespace TSTypeUtilsInternals {
: MaxImpl<N, [0, ...T]>;
}

// 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, B, Y, N> = [A] extends [B] ? ([B] extends [A] ? Y : N) : N;

// type ToLEQ<N extends number> = {
// [K in keyof LEQ]: [N] extends [RelaxedExclude<LEQ[K], K>] ? never : K;
// }[keyof LEQ];

// /**
// * The former part
// *
// * ```ts
// * type Main<
// * N extends number,
// * U extends number = ToLEQ<Extract<N, keyof LEQ>>
// * U extends number = ToLEQ<Extract<N, keyof LEQ>>,
// * > = {
// * [K in keyof LEQ]: Eq<U, LEQ[K], K, never>;
// * }
// * };
// * ```
// *
// * behaves like this
// * Behaves like this
// *
// * ```ts
// * type R = {
Expand All @@ -50,21 +50,16 @@ declare namespace TSTypeUtilsInternals {
// * }
// * ```
// */
// type Main<
// N extends number,
// U extends number = LEQ[Extract<N, keyof LEQ>]
// > = {
// type Main<N extends number, U extends number = ToLEQ<N>> = {
// [K in keyof LEQ]: Eq<U, LEQ[K], K, never>;
// }[keyof LEQ];
// }

// type Max<N extends Uint10> = _MaxImpl.Main<N>;

// type _MaxImpl<N extends Index<64>, T extends readonly unknown[]> = {
// b: T['length'];
// r: _MaxImpl<N, [0, ...T]>;
// }[[N] extends [Partial<T>['length']] ? 'b' : 'r'];
// // type MaxImpl<N extends Index<64>, T extends readonly unknown[]> = {
// // b: T['length'];
// // r: MaxImpl<N, [0, ...T]>;
// // }[[N] extends [Partial<T>['length']] ? 'b' : 'r'];
// }

// type Max<N extends Index<64>> = _MaxImpl<N, []>;
// type Max<N extends Uint10> = TSTypeUtilsInternals.Main<N>;

// https://stackoverflow.com/questions/62968955/how-to-implement-a-type-level-max-function-over-a-union-of-literals-in-typescri
16 changes: 7 additions & 9 deletions packages/ts-type-utils/src/min.d.mts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,11 @@ declare namespace TSTypeUtilsInternals {
: MinImpl<N, [0, ...T]>;
}

// type _MinImpl<
// N extends Index<64>,
// Count extends number
// > = IsNever<N> extends true
// ? never
// : 0 extends N
// ? Count
// : _MinImpl<Decrement<N>, Increment<Count> & number>;

// type Min<N extends Index<64>> = _MinImpl<N, 0>;
//
// type MinImpl<N extends Index<64>, Count extends number> =
// IsNever<N> extends true
// ? never
// : 0 extends N
// ? Count
// : _MinImpl<Decrement<N>, Increment<Count> & number>;
30 changes: 18 additions & 12 deletions packages/ts-type-utils/src/to-number.d.mts
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,36 @@ type ToNumber<S extends `${number}`> = S extends `${infer N extends number}`
? N
: never;

/* TypeScript v4.8 以前では以下の実装が必要 */

// type ToNumber<S extends `${number}`> =
// _ToNumberInternals._IsSmallNumber<S> extends true
// ? _MakeTupleInternals.MakeTupleImpl<unknown, S>['length']
// TSTypeUtilsInternals._IsSmallNumber<S> extends true
// ? TSTypeUtilsInternals.MakeTupleInternals.MakeTupleImpl<
// unknown,
// S,
// []
// >['length']
// : S;

// namespace _ToNumberInternals {
// declare namespace TSTypeUtilsInternals {
// // config
// type _DigitUpperLimit = 4;
// type DigitUpperLimit = 4;

// type _IsSmallNumber<S extends `${number}`> = _IsSmallNumberImpl<
// type IsSmallNumber<S extends `${number}`> = IsSmallNumberImpl<
// S,
// MakeTuple<unknown, _DigitUpperLimit>
// MakeTuple<unknown, DigitUpperLimit>
// >;

// 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 string> = T extends `${_Digit}${infer U}` ? U : never;
// type Tail<T extends string> = 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<Counter, readonly []> extends true
// ? false // reached the limit
// : _IsSmallNumberImpl<_Tail<S>, Tuple.Tail<Counter>>;
// ? false // reached the limit
// : IsSmallNumberImpl<Tail<S>, Tuple.Tail<Counter>>;
// }
2 changes: 0 additions & 2 deletions packages/ts-type-utils/src/uint-range.d.mts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ type UintRange<Start extends number, End extends number> = RelaxedExclude<
Index<Start>
>;

type IndexInclusive<N extends number> = IndexOfTuple<[...MakeTuple<0, N>, 0]>;

type UintRangeInclusive<
MinValue extends number,
MaxValue extends number,
Expand Down
37 changes: 7 additions & 30 deletions packages/ts-type-utils/src/utils.d.mts
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,17 @@ type TypeEq<A, B> =

type TypeExtends<A, B> = A extends B ? true : false;

/** Extract from T those types that are assignable to U */
type RelaxedExtract<T, U> = T extends U ? T : never;

/** From T, pick a set of properties whose keys are in the union K */
type RelaxedPick<T, K> = Pick<T, RelaxedExtract<keyof T, K>>;

/** Exclude from T those types that are assignable to U */
type RelaxedExclude<T, U> = T extends U ? never : T;

/** Construct a type with the properties of T except for those in type K. */
type RelaxedOmit<T, K extends keyof never> = Pick<
T,
RelaxedExclude<keyof T, K>
>;
type RelaxedOmit<T, K> = Pick<T, RelaxedExclude<keyof T, K>>;

/* type constants */

Expand Down Expand Up @@ -154,41 +157,15 @@ type MutableArrayOfLength<N extends number, Elm> = Mutable<

// https://qiita.com/uhyo/items/80ce7c00f413c1d1be56

type MutableArrayOfLengthOrMore<N extends number, Elm> = MutableArrayAtLeastLen<
N,
Elm
>;
type MutableArrayAtLeastLen<N extends number, Elm> = Mutable<
ArrayAtLeastLen<N, Elm>
>;

type ArrayOfLengthOrMore<N extends number, Elm> = ArrayAtLeastLen<N, Elm>;
type ArrayAtLeastLen<N extends number, Elm> = readonly [
...MakeTuple<Elm, N>,
...Elm[],
];

// type ArrayAtLeastLen<N extends number, Elm> = 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<R extends UnknownRecord> = {
[K in keyof R]: R[K];
};
Expand Down
6 changes: 3 additions & 3 deletions packages/ts-type-utils/test/array-of-length.mts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ expectType<ArrayOfLength<3, 0>, readonly [0, 0, 0]>('=');
expectType<ArrayOfLength<4, 1>, readonly [1, 1, 1, 1]>('=');
expectType<MutableArrayOfLength<4, 1>, [1, 1, 1, 1]>('=');

expectType<ArrayOfLengthOrMore<0, 0>, readonly 0[]>('=');
expectType<ArrayOfLengthOrMore<3, 0>, readonly [0, 0, 0, ...0[]]>('=');
expectType<ArrayOfLengthOrMore<4, 1>, readonly [1, 1, 1, 1, ...1[]]>('=');
expectType<ArrayAtLeastLen<0, 0>, readonly 0[]>('=');
expectType<ArrayAtLeastLen<3, 0>, readonly [0, 0, 0, ...0[]]>('=');
expectType<ArrayAtLeastLen<4, 1>, readonly [1, 1, 1, 1, ...1[]]>('=');

0 comments on commit 44fddde

Please sign in to comment.