// your answers
type IsTuple<T> = [T] extends [never]
? false
: T extends readonly any[]
? number extends T["length"]
? false
: true
: false;
Firstly,to check the type never.
Solution by shx123qwe #35065
// your answers
type IsTuple<T> = [T] extends [never]? false: T extends [] ? true: T extends readonly [infer P] ? true : false
Solution by gobielJonathan #34484
// 数组的length类型是number,要成为元组,T['length']需要精确数字类型(1、2等)而不仅仅是number类型。
type IsTuple<T> = [T] extends [never] ? false : T extends readonly any[] ? (number extends T['length'] ? false : true): false
Solution by ouzexi #34072
// your answers
type IsTuple<T> = [T] extends [never]
? false
: T extends readonly unknown[]
? number extends T['length']
? false
: true
: false
Solution by pea-sys #33072
// your answers
type IsTuple<T extends { length: number }> = [T] extends [never]
? false
: T extends any[] | readonly any[]
? T['length'] extends number
? number extends T['length']
? false
: true
: false
: false;
Solution by kakasoo #32688
type ReadonlyTuple<T extends readonly any[]> = T extends readonly []
? readonly []
: T extends readonly [infer Head]
? readonly [Head]
: T extends readonly [infer Head, ...infer Tail]
? readonly [Head, ...ReadonlyTuple<Tail>]
: never;
type TupleOrReadonlyTuple<T extends readonly any[]> = "push" extends keyof T ? [...ReadonlyTuple<T>] : ReadonlyTuple<T>;
type IsTuple<T> = [T] extends [never]
? false
: T extends ReadonlyArray<any>
? T extends TupleOrReadonlyTuple<T>
? true
: false
: false;
Solution by gasmg #32215
Just a different way of solution
type IsTuple<T> =
[T] extends [never]
? false
: "length" extends keyof T
? number extends T["length"]
? false
: number extends keyof T
? true
: false
: false
;
Solution by sdrjs #31687
type IsTuple<T> = [T] extends [never] ? false: T extends readonly unknown[] ? number extends T['length'] ? false: true : false
Solution by Yoon-Hae-Min #30546
type TupleElement = number | string | boolean | symbol | bigint | object | undefined | null
type IsTuple<T> =
[T] extends [never]
?
false
: T extends []
?
true
: T extends readonly [...any[]]
?
[] extends T
?
false
: T[0] extends TupleElement
?
true
: false
: false
Solution by zhangqiangzgz #30198
// your answers
// number extexts 1 ? false : true
// 1 extends number ? true : false
// tuple is fixed length
type IsTuple<T> = [T] extends [never]? false :
T extends readonly unknown[] ?
number extends T["length"] ?
false :
true :
false
Solution by kerolossamir165 #29041
type IsTuple<T> = [T] extends [never]
? false
: T extends readonly unknown[]
? number extends T["length"]
? false
: true
: false;
Solution by DoubleWoodLin #28741
type Shift<T> = T extends [] ? [] : T extends readonly [infer _, ...infer R] ? R : never;
type IsTuple<T> = Shift<T> extends never ? false : true;
Solution by breakinferno #28420
// 元组类型的 length 是数字字面量,而数组的 length 是 number。
type a = string[]["length"]; // number
type b = [string, string]["length"]; // 2
// 排除特殊情况,条件类型左边的裸类型如果是never,就会直接返回never
type IsTuple<T> = [T] extends [never]
? false
: T extends readonly any[]
? number extends T["length"]
? false
: true
: false;
Solution by jiaowoxiaobala #27985
type IsTuple<T> = T extends readonly [] ? true : T extends readonly [infer C, ...infer K] ? true : false
Solution by HenrryShaw #27748
type IsTuple<T> = [T] extends [never] ? false : T extends readonly unknown[] ? number extends T['length'] ? false : true : false
Solution by jiechliu #27700
type IsTuple<T> = [T] extends [readonly [...infer R]] ? (number extends R['length'] ? false : true) : false;
Solution by rldnd #26971
type IsTuple<T extends readonly any[] | { length: number }> =
[T] extends [never] ?
false :
T extends readonly any[] ?
number extends T['length'] ?
false :
true :
false;
Solution by kakasoo #26511
type IsTuple<T> = [T] extends [never]
? false
: T extends readonly unknown[]
? number extends T['length']
? false
: true
: false;
Solution by yungo1846 #25638
Determining whether an input is a tuple is a wild ride into the theory of TypeScript's type system. This is probably one of the most educational challenges to date. So many concepts are necessary to cover to arrive at some of the solutions. It's a valuable challenge, for sure!
// ============= Test Cases =============
import type { Equal, Expect } from './test-utils'
type A1 = IsTuple<[]>;
type B1 = true;
type C1 = Expect<Equal<A1, B1>>;
type A2 = IsTuple<[number]>;
type B2 = true;
type C2 = Expect<Equal<A2, B2>>;
type A3 = IsTuple<readonly [1]>;
type B3 = true;
type C3 = Expect<Equal<A3, B3>>;
type A4 = IsTuple<{ length: 1 }>;
type B4 = false;
type C4 = Expect<Equal<A4, B4>>;
type A5 = IsTuple<number[]>;
type B5 = false;
type C5 = Expect<Equal<A5, B5>>;
type A6 = IsTuple<never>;
type B6 = false;
type C6 = Expect<Equal<A6, B6>>;
// I added this case :)
type A7 = IsTuple<any>;
type B7 = false;
type C7 = Expect<Equal<A7, B7>>;
// ============= Your Code Here =============
// when doing `number extends T['length']`:
// - an array's "length" is `number`
// - a tuple's "length" is a specific number literal
type W = 1 extends 1 ? true : false; // true
type X = number extends number ? true : false; // true
type Y = number extends 1 ? true : false; // false
type Z = 1 extends number ? true : false; // true
type IsAny<T> = 1 extends T & 0 ? true : false;
type A = any & 0; // any
type B = never & 0; // never
type C = unknown & 0; // 0
/*
| | [never] | never[] |
| --- | ------- | ------- |
| [T] | ✓ (0) | ✓ (1) |
| T[] | ✓ (2) | ✓ (3) |
*/
type IsNever0<T> = [T] extends [never] ? true : false;
type IsNever1<T> = [T] extends never[] ? true : false;
type IsNever2<T> = T[] extends [never] ? true : false;
type IsNever3<T> = T[] extends never[] ? true : false;
type IsNever<T> = [T] extends [never] ? true : false
type IsTuple<T> =
true extends IsAny<T> | IsNever<T>
? false
: T extends
| readonly [infer _Head, ...infer _Tail]
| readonly []
? true
: false;
// ============== Alternatives ==============
// doesn't handle `any`
// type IsTuple<T> =
// [T] extends [never] // is never
// ? false
// : T extends readonly [] // is empty tuple
// ? true
// : T extends readonly [infer _Head, ...infer _Tail]
// ? true
// : false
// type IsTuple<T> =
// [T] extends [never]
// ? false
// : T extends readonly any[]
// ? number extends T['length']
// ? false
// : true
// : false;
// type IsTuple<T> =
// [T] extends [never]
// ? false
// : T extends readonly unknown[]
// ? number extends T["length"]
// ? false
// : true
// : false;
// ================== NOPE ==================
// // doesn't handle `never`
// type IsTuple<T> =
// T extends readonly any[]
// ? number extends T['length']
// ? false
// : true
// : false
For more video solutions to other challenges: see the umbrella list! https://github.com/type-challenges/type-challenges/issues/21338
Solution by dimitropoulos #24328
type IsTuple<T> = [T] extends [never]
? false
: T extends readonly unknown[]
? number extends T['length']
? false
: true
: false
Solution by NeylonR #24268
type IsTuple<T extends object> = [T] extends [never] ? false : T extends readonly any[] ? number extends T[`length`] ? false : true : false;
Solution by E-uler #23952
type IsTuple<T extends any[] | readonly any[]> =
`${T["length"]}` extends `${infer F}${infer Rest}`
? F extends "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
? true
: false
: never;
Solution by ZegTsai #23030
type IsTuple<T> = [T] extends [never] ? false : T extends readonly any[] ?
number extends T['length'] ? false : true : false
Solution by snakeUni #22934
type IsTuple<T> =
[T] extends [never]
? false
: T extends readonly any[]
? number extends T['length']
? false
: true
: T extends {length:number}
? false
: true
Solution by Allengl #22849
// your answers
type IsTuple<T> = [T] extends [never] ? false: T extends readonly unknown[] ? number extends T['length'] ? false: true: false;
Solution by edisonLzy #22798
// your answers
type IsTuple<T> = [T] extends [never]
? false
: T extends readonly unknown[]
? number extends T["length"]
? false
: true
: false;
Solution by jxhhdx #22724
type IsTuple<T> = [T] extends [never]
? false
: T extends readonly any[]
? number extends T["length"]
? false
: true
: false;
Solution by codeisneverodd #22333
type IsTuple<T> = [T] extends [never] ? false : T extends readonly any[] ?
// non tuple types don't have a definitive number for their length
number extends T['length'] ? false: true : false;
Solution by Karamuto #21377
Return true when:
T is not never && (T is [] || T is of any length)
.
Additionally, this solution supports cases such as readonly [1, 2, 3]
and readonly []
.
type IsTuple<T> = [T] extends [never]
? false
: T extends readonly []
? true
: T extends readonly [infer _Head, ...infer _Tail]
? true
: false
Solution by hstevanoski #21309
// your answers
type IsTuple<T> =
[T] extends [never] ? false :
T extends [] ? true :
T extends readonly[infer F,...infer R] ? true : false
Solution by YqxLzx #20062