8000 4. FirstOfArray · Issue #7 · astak16/blog-ts-challenges · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
4. FirstOfArray #7
Open
Open
@astak16

Description

@astak16

题目

题目链接: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 关键字

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0