00014-easy-first

Back

## 题目
实现一个`First<T>`泛型,它接受一个数组`T`并返回它的第一个元素的类型。

例如:

```ts
type arr1 = ['a', 'b', 'c']
type arr2 = [3, 2, 1]

type head1 = First<arr1> // 应推导出 'a'
type head2 = First<arr2> // 应推导出 3

解答

//1 TS判断条件使用extend
type First<T extends readonly any[]> =T extends [] ?never: T[0]

解析

extends的两种用法

1.泛型约束

// 约束 T 必须是数组类型
type First<T extends any[]> = ...

2.条件类型

// 如果 T 能赋值给 [],就返回 never,否则返回 T[0]
T extends [] ? never : T[0]

为什么extends可以进行条件判断: T extends U ? X : Y 的意思是:"如果类型 T 可以赋值给类型 U,则返回 X,否则返回 Y"。

具体例子
type Test1 = [1, 2, 3] extends [] ? 'empty' : 'not empty' 
// → 'not empty'

type Test2 = [] extends [] ? 'empty' : 'not empty'
// → 'empty'

type Test3 = [number] extends [] ? 'empty' : 'not empty'  
// → 'not empty'

其他判断空数组的方法、

使用infer解构

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

使用length属性

type First<T extends any[]> = 
  T['length'] extends 0 ? never : T[0]

Solution by nyk233233 #37461

// Utility: get the first element type of a tuple/array.
// We use a conditional type to explicitly handle the `never[]` case.
type First<T extends any[]> = T extends never[] ? never : T[0];

What this does (plainly):

Solution by 3aluw #37422

type First<T extends any[]> = T extends [infer F, ...any[]] ? F : never;

Solution by minseonkkim #37370

各种牛牛的答案

type First<T extends any[]> = T extends [] ? never : T[0];
type First<T extends any[]> = T['length'] extends 0 ? never : T[0];
type First<T extends any[]> =  T extends [infer U, ...infer reset] ? U : never;

Solution by djdidi #37119

// 你的答案
type First<T extends any[]> = T extends [infer H,...any[]]?T[0]:never;

Solution by lixinqiany #37109

type First<T extends any[]> = T['length'] extends 0 ? never : T[0]

Solution by dqks #37088

type First<T extends any[]> = T extends [infer F, ...infer R] ? F : never

Solution by 359Steve #37013

The solution to this problem can't just be the first element of the array. Since there is a test case that checks for undefined and [] arrays, which is the main challenge of this problem.

Solution 1

type First<T extends any[]> =T extends []? never:T[0]

Here T extends [] means if T is an empty array or not. If not, then simply return the first element.

Solution 2

type First<T extends any[]> =T["length"] extends 0 ? never:T[0]

Here T["length"] extends 0 checks for the length of the array.

Solution by Anonymous961 #36962

解题思路

看到这题的时候,我下意识的这样写

type First<T extends any[]> = T[0];

但是测试用例Expect<Equal<First<[]>, never>>, 没有通过,空数组应该返回never

所以,我尝试这样写

type First<T extends any[]> = T extends [] ? never : T[0];

成功了,这里是通过extends判断T是否是[]的子类型判断来T是否为空数组,关于 extends的这种三元表达式的用法,可以参考这里

看了下其他答案,也有比较好的写法,比如:

type First<T extends any[]> = T["length"] extends 0 ? never : T[0];

它通过T["length"]是否是0来判断数组是否是空数组。

还有另一个写法

type First<T extends any[]> = T extends [infer F, ...infer _] ? F : never;

关于infer的用法,可以参考精读《Typescript infer 关键字》

题解

type First<T extends any[]> = T extends [] ? never : T[0];

// type First<T extends any[]> = T["length"] extends 0 ? never : T[0];
// type First<T extends any[]> = T extends [infer F, ...infer _] ? F : never;

心得与知识点

  1. 条件运算符 extends...?:可以根据当前类型是否符合某种条件,返回不同的类型。
T extends U ? X : Y

上面式子中的extends用来判断,类型 T 是否可以赋值给类型U,即T是否为U的子类型,这里的TU可以是任意类型。

  1. 精读《Typescript infer 关键字》

Solution by lkwavestian #36946

// your answers
type First<T extends any[]> = T extends [infer F, ...infer Last] ? F : never

Solution by AlexBraunMagic #36918

type First<T extends any[]> = T extends [infer first, ...infer rest] ? first : never; 

Solution by shaishab316 #36841

type First<T extends any[]> = T extends [] ? never : T[0];

/* _____________ Test Cases _____________ */
import type { Equal, Expect } from '@type-challenges/utils'

type cases = [
  Expect<Equal<First<[3, 2, 1]>, 3>>,
  Expect<Equal<First<[() => 123, { a: string }]>, () => 123>>,
  Expect<Equal<First<[]>, never>>,
  Expect<Equal<First<[undefined]>, undefined>>,
]

type errors = [
  // @ts-expect-error
  First<'notArray'>,
  // @ts-expect-error
  First<{ 0: 'arrayLike' }>,
]

Solution by AnastasiaSv #36761

type First<T extends any[]> = T extends [] ? never : T[0];

Solution by Abdullah-Elsayed01 #36744

type First<T extends any[]> = T['length'] extends 0 ? never : T[0]

Solution by tungulin #36713

type First<T extends (string|number)[]> =   T[0];

Solution by Mamdouhreda #36707

// 你的答案
type First<T extends any[]> = T extends [] ? never : T[0]

Solution by PurplePlanen #36699

type First<T extends any[]> = T extends [] ? never : T[0]

type First<T extends any[]> = T extends [infer U, ...any[]] ? U : never

Solution by seungdeok #36657

// 你的答案
type First<T extends any[]> = T['length'] extends 0 ? never : T[0]

Solution by MrSissel #36580

// 你的答案
type First<T extends any[]> = T extends []?never : T[0]

Solution by mola-fish #36575

type First<T extends any[]> = T extends [infer F, ...any[]] ? F : never

Solution by ChemieAi #36549

// 你的答案

type First<T extends any[]> = T extends [infer U,...any[]]?U:never;

Solution by Rocco10086 #36536

type First<T extends any[]> = T extends [infer F, ...any[]] ? F : never;

Solution by saalehpxo #36509

type First<T extends any[]> = T extends [] ? never : T[0]

Solution by UsGitHu611 #36494

type First<T extends any[]> = T extends [infer K,...infer R] ? K : never;

Solution by gakki-san #36442

type First<T extends any[]> = T extends [infer R, ...any[]] ? R : never;

Solution by alirezaprime #36411

// your answers
type First<T extends any[]> = T extends [infer U, ...infer V] ? U : never;

Solution by justBadProgrammer #36358

// 你的答案
type First<T extends any[]> =T extends [infer F,...any[]] ? F : never

Solution by ATravelerGo #36351

type First<T extends any[]> = T extends [infer F, ...any[]] ? F : never

Solution by 1Alex4949031 #36309

type First<T extends any[]> =  T extends [infer U, ...infer _K] ? U : never

Solution by Jace254 #36266

type First<T extends any[]> = T extends [infer K, ...any] ? K : never

Solution by Maxim-Do #36224