09384-hard-maximum

Back

// remove U from tuple T
type Remove<T extends unknown[], U> = T extends [infer First, ...infer Rest]
  ? First extends U
    ? Remove<Rest, U>
    : [First, ...Remove<Rest, U>]
  : [];

type Maximum<T extends unknown[], Counter extends 0[] = []> = T extends []
  ? never
  : T["length"] extends 1
  ? T[0]
  : Maximum<Remove<T, Counter["length"]>, [...Counter, 0]>;

type Minimum<T extends unknown[], Counter extends 0[] = []> = T extends []
  ? never
  : Counter["length"] extends T[number]
  ? Counter["length"]
  : Minimum<T, [...Counter, 0]>;

test case for Minimum

Expect<Equal<Minimum<[]>, never>>,
Expect<Equal<Minimum<[0, 2, 1]>, 0>>,
Expect<Equal<Minimum<[1, 20, 200, 150]>, 1>>

Solution by yukicountry #34461

// 数组一直加元素,到最后Exclude<U, N['length']>就是到数组长度到最大的情况
type Maximum<T extends any[], K = T[number], U extends 0[] = []> = T extends [] ? never : Equal<K, U['length']> extends true ? K : Maximum<T, Exclude<K, U['length']>, [...U, 0]>

Solution by ouzexi #34332

type Maximum<T extends number[], Max extends number = never> = T extends [
  infer N extends number,
  ...infer R extends number[]
]
  ? Greater<N, Max> extends true
    ? Maximum<R, N>
    : Maximum<R, Max>
  : Max;

// 比较A 是否比 B 大
type Greater<
  A extends number,
  B extends number,
  Count extends 1[] = []
> = number extends A | B
  ? false
  : A extends Count["length"]
  ? B extends Count["length"]
    ? false
    : false
  : B extends Count["length"]
  ? true
  : Greater<A, B, [...Count, 1]>;

Solution by Vampirelee #32690

Can handle situations where there are large numbers in the array:

playgroud

type CompareNumLess10<A extends number, B extends number, Acc extends any[] = []> =
  A extends B
    ? 0
    : A extends Acc['length']
      ? -1
      : B extends Acc['length']
        ? 1
        : CompareNumLess10<A, B, [...Acc, any]>

type DropFirst<S extends number[]> = 
  S extends [infer _, ...infer Rest extends number[]]
    ? Rest
    : never

type NumToArray<N extends number, S extends string = `${N}`, R extends number[] = []> =
  S extends `${infer F extends number}${infer Rest}`
    ? NumToArray<N, Rest, [...R, F]>
    : R

type CompareNumArray<A extends number[], B extends number[]> = 
  A['length'] extends B['length']
    ? A['length'] extends 0
      ? 0
      : CompareNumLess10<A[0], B[0]> extends 0
        ? CompareNumArray<DropFirst<A>, DropFirst<B>>
        : CompareNumLess10<A[0], B[0]>
    : Compare<A['length'], B['length']>

type Compare<A extends number, B extends number> = CompareNumArray<NumToArray<A>, NumToArray<B>>

type Maximum<T extends number[], R extends number = never> = 
  T extends [infer F extends number, ...infer Rest extends number[]]
    ? [R] extends [never]
      ? Maximum<Rest, F>
      : Compare<R, F> extends -1
        ? Maximum<Rest, F> // R < F
        : Maximum<Rest, R>
    : R

First we need to implement a compare type:

// todo: 
// A === B return 0
// A > B return 1
// A < B return -1
type Compare<A extends number, B extends number> = 0 | -1 | 1

Then we can easily solve this problem by Compare:

type Maximum<T extends number[], R extends number = never> = 
  T extends [infer F extends number, ...infer Rest extends number[]]
    ? [R] extends [never]
      ? Maximum<Rest, F>
      : Compare<R, F> extends -1
        ? Maximum<Rest, F> // R < F
        : Maximum<Rest, R>
    : R

So the focus is how to implement Compare type

1

type Compare<A extends number, B extends number, Acc extends any[] = []> =
  A extends B
    ? 0
    : A extends Acc['length']
      ? -1
      : B extends Acc['length']
        ? 1
        : Compare<A, B, [...Acc, any]>

It's good enough to pass the test, but for relatively large numbers, an error will be thrown.

// Type instantiation is excessively deep and possibly infinite.ts(2589)
type ee = Compare<1001, 1002>

2

compare num less 10

using the above method

type CompareLess10<A extends number, B extends number, Acc extends any[] = []> =
  A extends B
    ? 0
    : A extends Acc['length']
      ? -1
      : B extends Acc['length']
        ? 1
        : CompareLess10<A, B, [...Acc, any]>

type a = CompareNumLess10<9, 8> // 1
type b = CompareNumLess10<8, 8> // 0
type c = CompareNumLess10<2, 8> // -1

compare num bigger then 9

  1. Put the numbers in each index of the array into an array in sequence
  2. Compare the converted array lengths
    1. If they are equal, compare the numbers at each position in the array in sequence.
    2. If they are not equal, just compare lengths.

// step 1
type NumToArray<N extends number, S extends string = `${N}`, R extends number[] = []> =
  S extends `${infer F extends number}${infer Rest}`
    ? NumToArray<N, Rest, [...R, F]>
    : R

// [1, 2, 3, 4, 5, 6, 7]
type d = NumToArray<1234567>

// step 2
type CompareNumArray<A extends string[], B extends string[]> = 
  A['length'] extends B['length']
    // step 2.1 length equal
    ? A['length'] extends 0
      ? 0 
      : CompareNumLess10<A[0], B[0]> extends 0 // compare first number
        ? CompareNumArray<DropFirst<A>, DropFirst<B>> // first number is equal, compare rest
        : CompareNumLess10<A[0], B[0]> // return the result of compare first number
    // step 2.2 length different, compare length
    : Compare<A['length'], B['length']>

// compare type
type Compare<A extends number, B extends number> = CompareNumArray<NumToArray<A>, NumToArray<B>>

// 9123123123123
type aa = Maximum<[1,2,1000,9123123123123,3,89,5,99999, 12312123122]>

Solution by action-hong #32484

type Remove<T extends number[], G extends number> = T extends [
  infer U,
  ...infer R extends number[]
]
  ? G extends U
    ? Remove<R, G>
    : [U, ...Remove<R, G>]
  : [];
type Maximum<T extends any[], C extends 0[] = []> = T["length"] extends 0
  ? never
  : T["length"] extends 1
  ? T[0]
  : Maximum<Remove<T, C["length"]>, [0, ...C]>;

Solution by vangie #32314


type ExcludeByArray<T extends any[], U> = T extends [infer S, ...infer O] ? S extends U ? O : [S, ...ExcludeByArray<O, U>] : [];
type Maximum<T extends any[], C extends any[] = []> = 
  T['length'] extends 1 ? T[0] :
  T['length'] extends 0 ? never :
    C['length'] extends T[number] ? Maximum<ExcludeByArray<T, C['length']>, [1, ...C]> : Maximum<T, [1, ...C]>;

Solution by tarotlwei #31854

type Sort<
  T extends number,
  U extends number,
  K extends number[] = []
> = K["length"] extends T
  ? U
  : K["length"] extends U
  ? T
  : Sort<T, U, [...K, 1]>;

type Maximum<T extends number[]> = T extends []
  ? never
  : T extends [
      infer F1 extends number,
      infer F2 extends number,
      ...infer R extends number[]
    ]
  ? Maximum<[Sort<F1, F2>, ...R]>
  : T[0];

Solution by moonpoet #31198

// 解答をここに記入

// 指定された長さを持つ配列を返す
type CreateArr<N extends number, Counter extends never[] = []> = Counter["length"] extends N ? Counter : CreateArr<N, [...Counter, never]>

// 2つの非負整数から大きい方を返す
type Larger<X extends number, Y extends number> = CreateArr<X> extends [...CreateArr<Y>, ...never[]] ? X : Y

// 最大値を返す
type InnerMaximum<T extends number[]> = T extends [infer F extends number, ...infer Rest extends number[]] ? Larger<InnerMaximum<Rest>,  F> : 0

// [] だけ例外処理し、それ以外については InnnerMaximum で最大値を返す
type Maximum<T extends number[]> = T extends [] ? never : InnerMaximum<T>

Solution by Kakeru-Miyazaki #30979

type Compare<A, B, U extends any[] = []> = U['length'] extends A ? B : U['length'] extends B ? A : Compare<A, B, [...U, 1]>
type Maximum<T extends any[]> = T extends [] ? never : T extends [infer A, infer B, ...infer C] ? Maximum<[Compare<A, B>, ...C]> : T[0]

Solution by dreamluo-plus #30785

// your answers

type FilterMax<T, R extends number[]> = T extends [infer Head, ...infer Rest] ? Head extends R['length'] ? FilterMax<Rest, R> : [Head, ...FilterMax<Rest, R>] : []

type Maximum<T extends any[], R extends number[] = []> = T extends [] ? never : FilterMax<T, R> extends [] ? R['length'] : Maximum<FilterMax<T, R>, [...R, 0]>

Solution by 437204933 #29720

type IsUnion<T, U = T> = T extends any
  ? [U] extends [T]
    ? false
    : true
  : never

// Recursively add 1 element to Tup
// and exclude Tup['length'] from T,
// until T contains the last number
type UnionMaximum<T extends number, Tup extends unknown[] = []> = 
  IsUnion<T> extends false
    ? T
    : UnionMaximum<Exclude<T, Tup['length']>, [...Tup, unknown]>

type Maximum<T extends any[]> = UnionMaximum<T[number]>

Solution by lzl1918 #29517

/** Returns maximum of two numeric literal types */
type Max<A, B, Acc extends any[] = []> = Acc['length'] extends A
  ? B
  : Acc['length'] extends B
  ? A
  : Max<A, B, [...Acc, any]>

/** Returns max value of a tuple of number literals */
type Maximum<T extends any[]> = T extends [infer First, ...infer Rest]
  ? Rest['length'] extends 0
    ? First
    : Max<First, Maximum<Rest>>
  : never

Unlike #21928 this doesn't union the elements of the tuple and it does recursion through the elements of the tuple, rather than up to the max value (though the Max helper does this). If there's one value that's much larger than the others, this may be more efficient.

Minimum can be implemented using Max and following the same pattern:

/** Returns minimum of two numeric literal types */
type Min<A, B> = A extends Max<A, B> ? B : A

/** Returns min value of a tuple of number literals */
type Minimum<T extends any[]> = T extends [infer First, ...infer Rest]
  ? Rest['length'] extends 0
    ? First
    : Min<First, Minimum<Rest>>
  : never

One difference with this approach is in how it handles unions in the tuple:

type T = Maximum<[0 | 100, 50]>
//   ^? type T = 50

whereas other solutions would say that the max is 100. The problem doesn't say what the desired behavior is in this case, so either answer is fine.

Solution by danvk #28958

type ParseNumber<
  S extends string
> = 
  S extends `${infer I}.${infer D}`?
    [I,D]
    :[S,'']
// l -> -1 e->0 g->1
type CompareLength<
  A extends string,
  B extends string,
> = 
  A extends `${string}${infer AR}`?
    B extends `${string}${infer BR}`?
      CompareLength<AR,BR>
      :1
    : 
    B extends A?
      0:-1

type GreatConfig  = {
  "0": '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8'| '9'
  "1": '2' | '3' | '4' | '5' | '6' | '7' | '8'| '9',
  '2': '3' | '4' | '5' | '6' | '7' | '8'| '9',
  "3": '4' | '5' | '6' | '7' | '8'| '9',
  "4": '5' | '6' | '7' | '8'| '9',
  "5": '6' | '7' | '8'| '9',
  '6': '7' | '8'| '9',
  "7": '8'| '9'
  "8": '9',
  '9': never,
}

type CompareDigit<
  A extends string,
  B extends string,
> = 
  A extends B?
    0:
    A extends keyof GreatConfig?
      B extends GreatConfig[A]?
        -1:1
      :never

type CompareDigits<
  A extends string,
  B extends string,
> =
A extends `${infer AF}${infer AR}`?
    B extends `${infer BF}${infer BR}`?
        CompareDigit<AF, BF> extends infer CR?
            CR extends 0?
                CompareDigits<AR, BR>
                :CR
            :never
        : 1
  :
  B extends A?
    0:-1
    

type CompareNonNegetive<
  T extends string,
  U extends string,
  TP extends [string,string] = ParseNumber<T>,
  UP extends [string,string] = ParseNumber<U>,
  ByLength extends (0 | 1 | -1) = CompareLength<TP[0],UP[0]>
> = 

  ByLength extends 0?
    TP[0] extends UP[0]?
      CompareDigits<TP[1],UP[1]>
      :CompareDigits<TP[0],UP[0]>
    
    :ByLength


type LTE<
  A extends number,
  B extends number,
> = 
`${A}` extends `-${infer ABS_A}`?
  `${B}` extends `-${infer ABS_B}`?
    CompareNonNegetive<ABS_B,ABS_A> extends 1?false:true
    : true
  :
  `${B}` extends `-${string}`?
    false: 
    CompareNonNegetive<`${A}`,`${B}`> extends 1? false:true



type Max<
  T extends number[],
  R extends number
> =
T extends [infer F extends number,...infer L extends number[]]?
  LTE<R,F> extends true?
    Max<L,F>: Max<L,R>
  :R


type Maximum<T extends number[]> = 
T['length'] extends 0?
  never:
  Max<T,T[0]>

Solution by jiangshanmeta #28706

type NTuple<N extends number, Arr extends any[] = []> = Arr extends {
  length: N;
}
  ? Arr
  : NTuple<N, [...Arr, any]>;

type Sub<N1 extends number, N2 extends number> = NTuple<N1> extends [
  ...infer R,
  ...NTuple<N2>
]
  ? R["length"]
  : never;

type Comparator<A extends number, B extends number> = Sub<B, A> extends never
  ? true
  : false;

type Max<T extends number[], M extends number = T[0]> = T extends [
  infer F extends number,
  ...infer Rest extends number[]
]
  ? Max<Rest, Comparator<F, M> extends true ? F : M>
  : M;

Solution by slemchik03 #27659

题目本身没要求是负数情况,但是我这里添加负数情况,使用字符串判断结果



// 辅助类型
type NumToString<T extends number> = `${T}`
// 获取字符串长度
type GetStringLen<T extends string, U extends any[] = []> = T extends `${infer L}${infer R}` ? GetStringLen<R, [...U, L]> : U['length']
// 返回较小数字
type GetMinNumber<A extends number, B extends number, L extends any[] = []> = L['length'] extends A | B ? L['length'] extends A ? A : B : GetMinNumber<A, B, [...L, -1]>
// number is equal
type NumIsEqual<A extends number, B extends number> = A extends B ? true : false
// strlen is equal
type StrLenIsEqual<A extends string, B extends string> = GetStringLen<A> extends GetStringLen<B> ? true : false
// 返回较大值 A B 属于 0-9 A1 B1 为原始值
type GetMaxNumber<A extends number, B extends number, A1 extends number = A, B1 extends number = B, isAllNegative extends boolean = false,>
  = A extends GetMinNumber<A, B> ? isAllNegative extends true ? A1 : B1 : isAllNegative extends true ? B1 : A1

// 判断是否是负数
type IsNegative<T extends number> = `${T}` extends `-${infer A extends number}` ? true : false

// 获取绝对值
type GetNegative<T extends number> = `${T}` extends `-${infer A extends number}` ? A : T



type Compare<
  A extends number,
  B extends number,
  isAllNegative extends boolean = false,
  A1 extends number = A,
  B1 extends number = B,
  S1 extends string = NumToString<A>,
  S2 extends string = NumToString<B>
> =
  StrLenIsEqual<S1, S2> extends true ?
  (
    S1 extends `${infer L1 extends number}${infer R1}` 
    ? S2 extends `${infer L2 extends number}${infer R2}`
    // 比较单个字符串对应数字情况
    ? NumIsEqual<L1, L2> extends true ?
    // 相等递归下一次
    Compare<A, B, isAllNegative, A1, B1, R1, R2> :
    // 不相等话比较数字大小
    GetMaxNumber<L1, L2, A1, B1, isAllNegative>
    // 对比到此处说明 A1 === B1 所以任意返回一个值就行了
    : A1 : A1
  ) 
  : 
  (
    // 转换成字符串后长度不相等
    GetStringLen<S1> extends GetMinNumber<GetStringLen<S1>, GetStringLen<S2>> ?
    // S1 长度小于 S2
    isAllNegative extends false ? B1 : A1 :
    // S1长度大于 S2
    isAllNegative extends false ? A1 : B1
  )
// 分为四种情况
// 1 A>= 0 B>=0     ===========> 比较 length ,谁的 length 大 返回谁
// 2 A>0 B<0        ===========> 直接返回 A
// 3 A<0 B>0        ===========> 直接返回 B
// 4 A<0 B<0        ========== > 谁的length小,值越大
type Max<A extends number, B extends number> =
IsNegative<A> extends true
? IsNegative<B> extends true
// A < 0 , B < 0
? Compare<GetNegative<A>, GetNegative<B>, true, A, B> : B
: IsNegative<B> extends true ? A : Compare<A, B>



// 答案
type Maximum<T extends number[], M extends number = T[0], First extends boolean = true> =
T['length'] extends 0 ? (
  First extends true ? never : M
) :
T extends [infer A extends number, ...infer B extends number[]] ?
Maximum<B, Max<A, M>, false> : M


// test
type N1 = NumToString<100>
type N2 = NumToString<20>
type S1 = GetStringLen<N1>

// test  GetMaxNumber
type G1 = GetMaxNumber<1, 2, 100, 200> // 200
type G2 = GetMaxNumber<1, 2, 100, 200>  // 200
type G3 = GetMaxNumber<2, 1, -200, -100, true> // -100
type G4 = GetMaxNumber<1, 2, -100, -200, true> // -100
type G5 = GetMaxNumber<1, 1, 10, 10, false> // 10
type G6 = GetMaxNumber<1, 1, 10, 10, false> // 


//test
type A1 = Max<30000000, 20000000> // 30000000
type A2 = Max<20000000, 30000000> // 30000000
type B1 = Max<0, 100000000> // 100000000
type B2 = Max<100000000, 0> // 100000000
type C1 = Max<-10000000000, -20000000000> // -10000000000
type C2 = Max<-20000000000, -10000000000> // -10000000000
type D1 = Max<-20000000, -10000000000000> // -20000000
type D2 = Max<-10000000000000, -20000000> // -20000000
type E1 = Max<-30000000, -30000000> // -30000000
type E2 = Max<-30000000, -30000000> // -30000000

// test
type arr0 = Maximum<[]> // never
type arr1 = Maximum<[-100000, -2000000, -2000000, -150000000]> // -100000
type arr2 = Maximum<[-10, -200000, -2000, -1500000000]> // -10
type arr3 = Maximum<[100000000, 20000, 20000, -150000]> // 100000000
type arr4 = Maximum<[0, -1]> // 0
type arr5 = Maximum<[-1, 1]> // 1

Solution by wuxin0011 #27595


// 设置一个默认值为0
// 当 C['length'] === A | B 时退出递归
// 判断 C['length'] === A or  C['length'] === B 先 === 的为较小值
// 不过这种方式当 A B 值为 负数时 该方案错误!
// 因此分为四种情况
// 1 A>= 0 B>=0     ===========> 比较 length ,谁的 length 大 返回谁
// 2 A>0 B<0        ===========> 直接返回 A
// 3 A<0 B>0        ===========> 直接返回 B
// 4 A<0 B<0        ========== > 谁的length小,值越大
// isAllNegative 表示两个数是否为负数
// A B 表示绝对值
// A1 表示 A 对应 如果A 是正数,L 和也是正数 如果 A = 1 ,L = 1 =>1; A = 1,A1 = -1 => -1
// B1 同 A1与 A 对应关系
type Compare<A extends number, B extends number, isAllNegative extends boolean = false, A1 extends number = A, B1 extends number = B, C extends any[] = []> =
  C['length'] extends A | B ?
  C['length'] extends A ? isAllNegative extends true ? A1 : B1 : isAllNegative extends true ? B1 : A1
  : Compare<A, B, isAllNegative, A1, B1, [...C, unknown]>


// 辅助类型
// 判断是否是负数
type IsNegative<T extends number> = `${T}` extends `-${infer A extends number}` ? true : false

// 获取绝对值
type GetNegative<T extends number> = `${T}` extends `-${infer A extends number}` ? A : T


// 两个负数数字越小值越大!
// 如果是一个正数和一个负数 就没必要对比了直接返回正数
type Max<A extends number, B extends number> =
  IsNegative<A> extends true
  ? IsNegative<B> extends true
  // A < 0 , B < 0
  ? Compare<GetNegative<A>, GetNegative<B>, true, A, B> : B
  : IsNegative<B> extends true ? A : Compare<A, B>




type arr = [-1, 20, -200, -150]

type Maximum<T extends number[], M extends number = T[0], First extends boolean = true> =
  T['length'] extends 0 ? (
    First extends true ? never : M
  ) :
  T extends [infer A extends number, ...infer B extends number[]] ?
  Maximum<B, Max<A, M>, false> : M



type M = Maximum<arr>



// test
type A1 = Max<10, 2> // 10
type A2 = Max<2, 10> // 10
type B1 = Max<0, 1> // 1
type B2 = Max<0, -1> // 0
type C1 = Max<-1, 1> // 1
type C2 = Max<1, -1> // 1
type D1 = Max<-2, -1> // -1
type D2 = Max<-1, -2> // -1
type E1 = Max<-100, -200> // -100
type E2 = Max<-200, -100> // -100

// test
type arr0 = Maximum<[]> // never
type arr1 = Maximum<[-1, 20, -200, -150]> // 20
type arr2 = Maximum<[-1, -20, -200, -150]> // -1
type arr3 = Maximum<[1, 20, 200, -150]> // 200
type arr4 = Maximum<[0, -1]> // 0
type arr5 = Maximum<[-1, 1]> // 1

Solution by wuxin0011 #27585

type NumberToTuple<
  N extends number,
  Tuple extends never[] = [],
> = Tuple['length'] extends N ? Tuple : NumberToTuple<N, [...Tuple, never]>;

type Maximum<T extends number[]> = T extends [] ? never : Maximum.Get<T, []>;
namespace Maximum {
  export type Get<T extends number[], Max extends never[]> = T extends [
    infer T0 extends number,
    ...infer TRest extends number[],
  ]
    ? `${T0}` extends keyof Max
      ? Maximum.Get<TRest, Max>
      : Maximum.Get<TRest, NumberToTuple<T0, Max>>
    : Max['length'];
}

Playground

Solution by BOCbMOU #27533

type Maximum<T extends any[], U = T[number], C extends 1[] = []> = T extends []
  ? never
  : [U] extends [C['length']]
  ? U
  : Maximum<T, U extends C['length'] ? never : U, [...C, 1]>;

type Minimum<T extends any[], C extends 1[] = []> = T extends []
  ? never
  : C['length'] extends T[number]
  ? C['length']
  : Minimum<T, [...C, 1]>;

Test cases

type cases = [
  Expect<Equal<Maximum<[]>, never>>,
  Expect<Equal<Maximum<[0, 2, 1]>, 2>>,
  Expect<Equal<Maximum<[1, 20, 200, 150]>, 200>>,
  Expect<Equal<Maximum<[0]>, 0>>,
  Expect<Equal<Minimum<[]>, never>>,
  Expect<Equal<Minimum<[0, 2, 1]>, 0>>,
  Expect<Equal<Minimum<[1, 20, 200, 150]>, 1>>,
  Expect<Equal<Minimum<[0]>, 0>>
];

Solution by JohnLi1999 #26172

//思路:将数字转成数组,提取高级类型IsLessThan通过同时遍历两个数组看谁先结束来比较数字大小。
// 最后依次遍历原数组,预设Max泛型参数与当前遍历的数字比较大小从而更新max直到遍历完原数组,max即为最大值。
type Num2Tuple<N extends number, Res extends unknown[] = []> = Res['length'] extends N ? Res : Num2Tuple<N, [...Res, unknown]>

type IsLessThan<N1 extends number, N2 extends number, L extends unknown[] = Num2Tuple<N1>, R extends unknown[] = Num2Tuple<N2>> =
    L extends [infer CurL, ...infer RestL] ? R extends [infer CurR, ...infer RestR] ?
    IsLessThan<RestL['length'], RestR['length']> : false : true

type Maximum<T extends number[], Max extends number = 0, InitialT extends number[] = T> =
    InitialT['length'] extends 0 ? never :
    T extends [infer Cur extends number, ...infer Rest extends number[]] ?
    IsLessThan<Max, Cur> extends true ? Maximum<Rest, Cur, InitialT> : Maximum<Rest, Max, InitialT> : Max

Solution by zhuizhui0429 #25912

type Maximum<T extends any[], _Counter extends 1[] = [], _Result extends number = never, _Next extends 1[] = [..._Counter, 1]> =
  _Counter[`length`] extends 999 ? _Result/*return*/ :
  Maximum<T, _Next, _Next[`length`] extends T[number] ? _Next[`length`] : _Result>; //1000以内

// old way
// type Digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
// type Digit = Digits[number];
// type Number<T extends string | number> = `${T}` extends `${infer N extends number}` ? N : never;
// type Length<T extends string, _Counter extends 1[] = []> = T extends `${any}${infer R}` ? Length<R, [..._Counter, 1]> : _Counter[`length`];
// type First<T extends string | number> = `${T}` extends `${infer F extends Digit}${any}` ? F : 0;
// type Rest<T extends string | number> = `${T}` extends `${number}${infer R}` ? R : ``;
// type DigitLargeThan<T extends Digit, U extends Digit, _Iter extends Digit[] = Digits> = T extends U ? false : _Iter extends [...infer R extends Digit[], infer L] ? (L extends T ? true : L extends U ? false : DigitLargeThan<T, U, R>) : false;
// /**是否大于 */
// type LargeThan<T extends number | string, U extends number | string> = `${T}${U}` extends `` ? false :  //return
//   Length<`${T}`> extends Length<`${U}`> ?                 //长度相等,比较位数
//   (First<Number<T>> extends First<Number<U>> ?
//     LargeThan<Rest<T>, Rest<U>> :                         //高位相等,比较更低位
//     (DigitLargeThan<First<Number<T>>, First<Number<U>>>)  //高位不等,比较大小
//   )
//   : LargeThan<Length<`${T}`>, Length<`${U}`>>             //长度不等,长的大

// type Maximum<T extends number[], _Result extends number = never> = T extends [infer F extends number, ...infer R extends number[]] ?
//   Maximum<R, [_Result] extends [never] ? F : (LargeThan<F, _Result> extends true ? F : _Result)> :
//   _Result;  //return

Solution by E-uler #25121

type ReturnGreater<T extends number, U extends number, Acc extends unknown[] =[]> = T extends Acc['length']
? U
: U extends Acc['length']
  ? T
  : ReturnGreater<T, U, [...Acc, '']>

type Maximum<T extends unknown[]> = T extends [infer First extends number, infer Second extends number, ...infer Rest]
? Rest extends []
  ? ReturnGreater<First, Second>
  : Maximum<[ReturnGreater<First, Second>, ...Rest]>
: never

Solution by NeylonR #24600

type GreaterThan<T extends number, U extends number, A extends number[] = []> = T extends U
 ? false
 : A['length'] extends U
 ? true
 : A['length'] extends T
 ? false
 : GreaterThan<T, U, [0, ...A]>

type Maximum<T extends number[], U extends number = T[0], Max extends number = never> = 
 T extends [ infer F extends number, ...infer R extends number[] ]
   ? Maximum<R, F, [Max] extends [never] ?  F : GreaterThan<Max, F> extends true ? Max : F>
   : Max

Solution by TKBnice #23550

// your answers
type ReturnMax<
  A,
  B,
  Len extends unknown[] = []
> = A extends Len['length']
  ? B
  : B extends Len['length']
    ? A
    : ReturnMax<A, B, [unknown, ...Len]>;
type Maximum<
  T extends any[]
> = T extends [infer F extends number, infer S extends number,...infer Rest] 
      ? 0 extends Rest['length']
        ? ReturnMax<F, S>
        : Maximum<[ReturnMax<F, S>, ...Rest]>
      : never;

Solution by jxhhdx #23307

type GreaterThan<
  T extends number,
  U extends number,
  R extends unknown[] = [],
> = T extends R['length']
  ? false
  : U extends R['length']
    ? true
    : GreaterThan<T, U, [...R, 0]>

type Maximum<T extends number[]> =
  T extends []
    ? never
    : T extends [infer A extends number, infer B extends number, ...infer Rest extends number[]]
      ? Maximum<[GreaterThan<A, B> extends true ? A : B, ...Rest]>
      : T[0]

Solution by drylint #22981

// Maximum
type Maximum<T extends number[]>
  = keyof {[I in T[number] as ['<'] extends [keyof {[J in Exclude<T[number], I> as Compare<`${I}`, `${J}`>]: never}] ? never : I]: never}

// Minimum
type Minimum<T extends number[]>
  = keyof {[I in T[number] as ['>'] extends [keyof {[J in Exclude<T[number], I> as Compare<`${I}`, `${J}`>]: never}] ? never : I]: never}

// Comapre Numbers
type Compare<A extends string, B extends string, P extends string = '='>
  = A extends B ? P
  : `${A} ${B}` extends `${infer C}${infer X} ${infer D}${infer Y}`
    ? P extends '<' | '>' ? Compare<X, Y, P>
    : C extends D ? Compare<X, Y, P>
    : '9876543210' extends `${any}${C}${any}${D}${any}` ? Compare<X, Y, '>'>
    : Compare<X, Y, '<'>
  : A extends '' ? '<' : '>'

Playground

Solution by teamchong #22541

type NTuple<N extends number, C extends unknown[]=[]> = C['length'] extends N | never ? C : NTuple<N, [...C, 0]>;

type Maximum<T extends unknown[], H extends number = never> = T extends [infer N extends number, ...infer Rest] ?
  Maximum<Rest, NTuple<N> extends [...NTuple<H>, ...any] ? N : H> 
: H;
// extra never check to be able to get 0 as minimum
type Minimum<T extends unknown[], H extends number = never> = T extends [infer N extends number, ... infer Rest] ?
 Minimum<Rest, Equal<H,never> extends true ? N : [...NTuple<H>, ...any] extends NTuple<N> ? N : H > : H;

Solution by Karamuto #22232

// your answers
type GreaterThan<
  D1 extends number,
  D2 extends number,
  hasEqual extends boolean = false,
  A extends unknown[] = []
> = D1 extends D2
  ? hasEqual
  : A["length"] extends D1
  ? false
  : A["length"] extends D2
  ? true
  : GreaterThan<D1, D2, hasEqual, [unknown, ...A]>;
type TwoMaximum<A extends number, B extends number> = GreaterThan<
  A,
  B
> extends true
  ? A
  : B;
type Maximum<
  T extends number[],
  Res extends number = 0,
  IsFirst extends boolean = true
> = T extends [infer F extends number, ...infer R extends number[]]
  ? Maximum<R, TwoMaximum<Res, F>, false>
  : IsFirst extends true
  ? never
  : Res;

Solution by acwink #22151

type UniqueArray<T extends any[], Result extends any[] = []> = T extends [infer First, ...infer Rest]
  ? First extends Result[number]
    ? UniqueArray<Rest, Result>
    : UniqueArray<Rest, [...Result, First]>
  : Result;

type RemoveElement<T extends any[], E> = T extends [infer First, ...infer Rest]
  ? E extends First
    ? [...RemoveElement<Rest, E>]
    : [First, ...RemoveElement<Rest, E>]
  : [];

type Maximum<T extends number[] = [], Nums extends any[] = [], U extends any[] = UniqueArray<T>> = U['length'] extends 0
  ? never
  : U['length'] extends 1
  ? U[0]
  :  Nums['length'] extends U[number]
  ? Maximum<RemoveElement<U, Nums['length']>, [1, ...Nums]>
  : Maximum<U, [1, ...Nums]>;

Solution by zqiangxu #22104

// your answers
type CreateLen<T,A extends any[] = []> = A['length'] extends T ? A: A extends [...infer R] ? CreateLen<T,[1,...R]> : []

type EqualArrLen<T,P> = T extends [infer F,...infer R] ? P extends [] ? true : 
P extends [infer F1,...infer R1] ? EqualArrLen<R,R1> : false : false

type Maximum<T extends any[],X extends any = 0> = T extends [] ? never : 
T extends [infer F,infer M,...infer R] ? EqualArrLen<CreateLen<F>,CreateLen<M>> extends true ?
Maximum<[F,...R],F> : Maximum<[M,...R],M> : X 

Solution by YqxLzx #22072

type Number2Tuple<T extends number, _T extends unknown[] = []> = 
  _T['length'] extends T
  ? _T
  : Number2Tuple<T, [unknown, ..._T]>

type Max<A extends number, B extends number, _TA extends unknown[] = Number2Tuple<A>, _TB extends unknown[] = Number2Tuple<B>> =
  _TA extends [..._TB, ...any]
  ? A
  : B

type Maximum<T extends number[], _M extends number = 0> = 
  T extends [infer First extends number, ...infer Rest extends number[]]
  ? Rest extends []
    ? Max<First, _M>
    : Maximum<Rest, Max<First, _M>>
  : never

playground

Key points:

Solution by zhaoyao91 #22032