Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

4. FirstOfArray #7

Open
astak16 opened this issue Apr 5, 2022 · 0 comments
Open

4. FirstOfArray #7

astak16 opened this issue Apr 5, 2022 · 0 comments
Labels

Comments

@astak16
Copy link
Owner

astak16 commented Apr 5, 2022

题目

题目链接:FirstOfArray

实现一个 FirstOfArray 满足测试用例 cases,作用是返回数组中的第一项

  • 测试用例1: [3, 2, 1] 结果为 3
  • 测试用例2: [() => 123, { a: string }] 结果为 () => 123
  • 测试用例3: [] 结果为 never
  • 测试用例4: [undefined] 结果为 undefined
import { Equal, Expect } from "@type-challenges/utils";

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

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

答案

方法一

type FirstOfArray<Arr extends any[]> = 
  Arr extends [infer Item, ...any[]] ? Item : never;

知识点

  1. 泛型 Arr 继承自任意类型的数组
  2. infer Item 是声明一个 Item,类似于变量声明,在后面都可以使用
  3. [infer Item, ...any[]] 取出数组的第一项,放在变量 Item
    1. 通过 extends 判断泛型 Arr 是否继承自 [infer Item, ...any[]]
    2. 空数组 [] extends [infer Item, ...any[]] 结果为 false,所以输出为 never
    3. 其余情况为 true,输出数组第一项

方法二

type FirstOfArray<Arr extends any[]> = Arr extends [] ? never : Arr[0];

知识点

  1. [] extens []true 输出为 never
  2. 其余情况为 false 输出为 Arr[0]

方法三

type FirstOfArray<Arr extends any[]> = "0" extends keyof Arr ? Arr[0] : never;

知识点

  1. keyof Arr 取出数组中的每一个 key
  2. "0" extends keyof Arr 判断数组中有没第一项,因为空数组是没有第一项的。
  3. 如果有第一项,输出 Arr[0] 否则为 never

方法四

type FirstOfArray<Arr extends any[]> = Arr["length"] extends 0 ? never : Arr[0];

知识点

  1. Arr["length"] 可以获取泛型 Arr 的长度
  2. Arr["length"] extends 0 判断数组长度是否为 0
  3. 如果为 0 输出 never,否者输出 Arr[0]

方法五

type FirstOrArray<Arr extends any[]> = 
  Arr[number] extends never ? never : Arr[0];

知识点

  1. Arr[number] 可以得到数组的每一项值的联合类型

    type A1<Arr> = Arr[number]
    type A2: A1<[1, 2, 3]> // => 1 | 2 | 3
    
    type A3: A1<[]> // => never
  2. 如果是个空数组 Arr<[]> 会返回 never,通过判断 Arr[number] extends never 是否为 never

  3. 如果为 never 输出 never 否则输出 Arr[0]

方法六

type FirstOfArray<Arr extends any[]> = Arr[Extract<keyof Arr, "0">];

总结

空数组的几种判断方法

  • T extends []
  • T extends never[]
  • "0" extends keyof T
  • T["length"] extends 0
  • T[number] extends never

基础知识

  1. extends 用法
  2. 通俗易懂的讲解 infer 关键字
@astak16 astak16 added the easy label Apr 12, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant