27958-medium-checkrepeatedtuple

Back

type IsEqual<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? true : false;
type Includes<T extends any[], U extends string | number | symbol> = T extends [infer F, ...infer Rest]
  ? IsEqual<F, U> extends true
    ? true
    : Includes<Rest, U>
  : false;
type CheckRepeatedTuple<T extends unknown[]> = T extends [infer F extends string | number | symbol, ...infer Rest]
  ? Includes<Rest, F> extends true
    ? true
    : CheckRepeatedTuple<Rest>
  : false;

Solution by wendao-liu #35150

type Same<T, U extends any[]> = U extends [infer R, ...infer rest] ? (Equal<T, R> extends true ? true : Same<T, rest>) : false
type CheckRepeatedTuple<T extends unknown[]> = T extends [infer R, ...infer rest] ? Same<R, rest> : false

// 方法二
type CheckRepeatedTuple<T extends unknown[]> = T extends [infer R, ...infer rest] ? R extends rest[number] ? true : CheckRepeatedTuple<rest> : false

Solution by ouzexi #34168

type CheckRepeatedTuple<T extends unknown[], Other extends unknown[] = []> =
  T extends [infer A, ...infer Rest extends unknown[]]
    ? Includes<Rest, A> extends true
      ? true
      : CheckRepeatedTuple<Rest>
    : false

type Includes<Arr, E> =
  Arr extends [infer A, ...infer Rest]
    ? Equal<A, E> extends true
      ? true
      : Includes<Rest, E>
    : false

Solution by drylint #34142

// 你的答案
type Includes<T, K> = T extends [infer A, ...infer R] ? A extends K ? true : Includes<R, K> : false
type CheckRepeatedTuple<T extends unknown[]> = T extends [infer A, ...infer R] ? 
  Includes<R, A> extends true ? true : CheckRepeatedTuple<R>
  : false

Solution by heyuelan #33873

  type CheckRepeatedTuple<T extends any[]> = 
   T extends [infer A, ... infer R]
     ? A extends R[number]
         ? true
         : CheckRepeatedTuple<R>
     : false

Solution by sunupupup #33487

export type CheckRepeatedTuple<T extends unknown[]> = T extends [infer F, ...infer Rest]
  ? F extends Rest[number] 
    ? true
    : CheckRepeatedTuple<Rest>
  :false 
  

Solution by bananana0118 #33201

export type CheckRepeatedTuple<T extends unknown[]> = T extends [infer F, ...infer Rest]
  ? F extends Rest[number] 
    ? true
    : CheckRepeatedTuple<Rest>
  :false 
  

Solution by bananana0118 #33200

type CheckRepeatedTuple<T, K extends keyof T = keyof T & `${number}`>
  = [{[I in K]: {[J in Exclude<K, I>]: T[I] & T[J]}[Exclude<K, I>]}[K]] extends [never] ? false : true

Playground

Solution by teamchong #32999

type CheckRepeatedTuple<
  T extends unknown[],
  Pre extends unknown[] = []
> = T extends [infer L, ...infer R]
  ? Include<[...R, ...Pre], L> extends true
    ? true
    : CheckRepeatedTuple<R, [...Pre, L]>
  : false;


type Include<T extends any[], E> = T extends [infer L, ...infer R]
  ? Equal<L, E> extends true
    ? true
    : Include<R, E>
  : false;

Solution by Vampirelee #32586

type CheckRepeatedTuple<T extends unknown[], O extends unknown=never> = T extends [
  infer F,
  ...infer R
]
  ? F extends O
    ? true
    : CheckRepeatedTuple<R, O | F>
  : false;

Solution by vangie #32199

type CheckRepeatedTuple<T extends unknown[], U extends any = never> =
  T extends [infer F, ...infer R]
    ? [F] extends [U]
      ? true
      : CheckRepeatedTuple<R, U | F>
    : false

Solution by milletlovemouse #31028

type CheckRepeatedTuple<T extends unknown[]> = T extends [infer F, ...infer Rest]
  ? F extends Rest[number]
    ? true
    : CheckRepeatedTuple<Rest>
  : false;

Solution by leejaehyup #30943

type CheckRepeatedTuple<T extends unknown[]> = T extends [infer E, ...infer R]
  ? E extends R[number]
    ? true
    : CheckRepeatedTuple<R>
  : false

Solution by DevilTea #30909

type CheckRepeatedTuple<T extends unknown[]> = T extends [infer A, ...infer B] ? A extends B[number] ? true : CheckRepeatedTuple<B> : false

Solution by dreamluo-plus #30702

// your answers

type CheckRepeatedTuple<T extends unknown[]> = T extends [infer F , ...infer Rest ] ? F extends Rest[number] ? true : CheckRepeatedTuple<Rest> : false

Solution by kerolossamir165 #29396

type CheckRepeatedTuple<T extends unknown[]> = T extends [
  infer Item,
  ...infer R
]
  ? Item extends R[number]
    ? true
    : CheckRepeatedTuple<R>
  : false;

The solution in this case will be wrong,so the better solution should be using Equal to compare each item.

  Expect<Equal<CheckRepeatedTuple<[1, 2, 3,number]>, false>>,

Here is the solution by using IsEqual:

type IsEqual<A, B> = (<T>() => T extends A ? 1 : 2) extends <T>() => T extends B
  ? 1
  : 2
  ? true
  : false;

type CheckRepeatedTuple<T extends unknown[]> = T extends [
  infer Item,
  ...infer R
]
  ? R extends []
    ? false
    : Item extends R[number]
    ? IsEqual<Extract<R[number], Item>, Item> extends true
      ? true
      : CheckRepeatedTuple<R>
    : CheckRepeatedTuple<R>
  : false;

Solution by DoubleWoodLin #28922

type CheckRepeatedTuple<T extends unknown[], Before extends unknown[] = []> = T extends [infer L, ...infer R]
  ? L | Before[number] extends R[number]
  ? true
  : CheckRepeatedTuple<R, [...Before, L]>
  : false

Solution by ch3cknull #28682

递归遍历,判断是否在数组 U 中有这个字符,实现一个 Includes 来判断

type Includes<T extends readonly any[], U> = T extends [infer F, ...infer R] ? (IsEqual<U, F> extends true ? true : Includes<R, U>) : false
type IsEqual<A, B> = ((<T>() => T extends A ? true : false) extends (<T>() => T  extends B ? true : false) ? true : false )

type CheckRepeatedTuple<T extends unknown[], U extends unknown[] = []> = T extends [infer F, ...infer Rest]
  ? Includes<U, F> extends true
    ? true
    : CheckRepeatedTuple<Rest, [...U, F]>
  : false

Solution by linjunc #28602

type CheckRepeatedTuple<T extends unknown[], Cache = never> = T extends [infer Start, ...infer End]
  ? Start extends Cache
    ? true
    : CheckRepeatedTuple<End, Cache | Start>
  : false;

Solution by EGyoung #28258

type Shift<T extends any[]> = T extends [any, ...infer R] ? R : [];
type CheckOneRound<T extends any[], U extends any> = T extends [] ? false :
  U extends T[0] ? true : CheckOneRound<Shift<T>, U>;
type CheckRepeatedTuple<T extends unknown[], _Current = T[0]> = T extends [] ? false :
  CheckOneRound<Shift<T>, _Current> extends true ? true : CheckRepeatedTuple<Shift<T>>;

Solution by E-uler #28123

type CheckRepeatedTuple<T extends unknown[],U extends unknown[] = []> = 
T extends [infer F,...infer R]?
  F extends U[number]?
    true:
    CheckRepeatedTuple<R,[...U,F]>
  :false

Solution by jiangshanmeta #28032

type CheckRepeatedTuple<T extends unknown[], U = never> = T extends [
  infer F,
  ...infer R
]
  ? F extends U
    ? true
    : CheckRepeatedTuple<R, U | F>
  : false;
type Includes<T, U> = T extends [infer F, ...infer R]
  ? Equal<F, U> extends true
    ? true
    : Includes<R, U>
  : false;

type CheckRepeatedTuple<T extends unknown[]> = T extends [infer F, ...infer R]
  ? Includes<R, F> extends true
    ? true
    : CheckRepeatedTuple<R>
  : false;
type cases = [
  Expect<Equal<CheckRepeatedTuple<[number, number, string, boolean]>, true>>,
  Expect<Equal<CheckRepeatedTuple<[number, string]>, false>>,
  Expect<Equal<CheckRepeatedTuple<[1, 2, 3]>, false>>,
  Expect<Equal<CheckRepeatedTuple<[1, 2, 1]>, true>>,
  Expect<Equal<CheckRepeatedTuple<[]>, false>>,
  Expect<Equal<CheckRepeatedTuple<string[]>, false>>,
  Expect<Equal<CheckRepeatedTuple<[number, never, string, never]>, true>>,
  Expect<Equal<CheckRepeatedTuple<[any, never]>, false>>,
  Expect<Equal<CheckRepeatedTuple<[any, unknown]>, false>>,
  Expect<Equal<CheckRepeatedTuple<[number, any, string, any]>, true>>,
  Expect<Equal<CheckRepeatedTuple<[number, unknown, string, unknown]>, true>>,
  Expect<Equal<CheckRepeatedTuple<[any, unknown, never]>, false>>,
  Expect<
    Equal<
      CheckRepeatedTuple<
        [any, unknown, never, number, 0, string, '', boolean, true, false]
      >,
      false
    >
  >
];

Solution by JohnLi1999 #28021

type CheckRepeatedTuple<T extends unknown[]> = T extends [infer F, ...infer Rest]
  ? F extends Rest[number]
    ? true
    : CheckRepeatedTuple<Rest>
  : false

Solution by XkSuperCool #28012

type IsEqual<A, B> = (<X>() => X extends A ? 1 : 2) extends <X>() => X extends B
  ? 1
  : 2
  ? true
  : false;

type Includes<T extends unknown[], U> = T extends [infer F, ...infer Rest]
  ? IsEqual<F, U> extends true
    ? true
    : Includes<Rest, U>
  : false;

// number extends T['length']排除非元组类型,因为T有可能是string[]
// type arr1 = string[] -> arr1['length'] -> number
// type arr2 = [string] -> arr2['length'] -> 1
type CheckRepeatedTuple<T extends unknown[]> = number extends T["length"]
  ? false
  : // 递归遍历T,每次取出第一项
  T extends [infer F, ...infer Rest]
  ? // 判断后面的所有成员中是否有与第一项相等的
    Includes<Rest, F> extends true
    ? true
    : // 如果没有,继续递归后面的所有成员,此时第一项可以排除了
      CheckRepeatedTuple<Rest>
  : false;

Solution by jiaowoxiaobala #28009