30178-hard-unique-items

Back

type Ensure<T,  _P extends unknown[] = []> =
  T extends [ infer F, ...infer R ]
    ? Ensure<R, [ ..._P, F extends _P[number] ? never : F ]>
    : _P extends T ? _P : _P

function uniqueItems<const T>(items: Ensure<T>) {
  return items
}

Solution by lvjiaxuan #33601

type Ensure<T,  _P extends unknown[] = []> =
  T extends [ infer F, ...infer R ]
    ? Ensure<R, [ ..._P, F extends _P[number] ? never : F ]>
    : _P extends T ? _P : _P

function uniqueItems<const T>(items: Ensure<T>) {
  return items
}

Solution by lvjiaxuan #33600

type UniqueItemsTuple<T> = {[I in keyof T]
  : I extends `${number}`
    ? I extends Smallest<keyof {[J in keyof T & `${number}` as T[J] extends T[I] ? J : never]: never}> ? T[I]
    : { error: `Item duplicated at position ${I}` }
  : T[I]
}

type Smallest<N extends string>
  = keyof {[I in N as [keyof {[J in Exclude<N, I> as GreaterThan<I, J> extends true ? I : never]: never}] extends [never] ? I : never]: never}

type GreaterThan<X extends string, Y extends string, Gt extends boolean | undefined = undefined>
  = X extends Y ? Gt extends undefined ? false : Gt
  : `${X} ${Y}` extends `${infer A}${infer C} ${infer B}${infer D}`
    ? GreaterThan<C, D, Gt extends true | false ? Gt
        : A extends B ? Gt
        : '9876543210' extends `${any}${X}${any}${Y}${any}` ? true : false>
  : X extends '' ? false : true

function uniqueItems<const T>(items: T extends UniqueItemsTuple<T> ? T : UniqueItemsTuple<T>) {
  return items
}

Playground

Solution by teamchong #33165

type GenerateHintTuple<T, _U = never> = T extends [infer First, ...infer Rest]
  ? [First extends _U ? never : First, ...GenerateHintTuple<Rest, First | _U>]
  : []

function uniqueItems<const T>(items: T extends GenerateHintTuple<T> ? T : GenerateHintTuple<T>) {
  return items
}

Solution by Sun79 #33118