type-challenges:Join

20 阅读1分钟

Join

问题描述

实现类型版本的 Array.JoinJoin < T,U > 接受 Array Tstringnumber U,并在 U 拼接后返回 Array T

type Res = Join<["a", "p", "p", "l", "e"], "-">; // expected to be 'a-p-p-l-e'
type Res1 = Join<["Hello", "World"], " ">; // expected to be 'Hello World'
type Res2 = Join<["2", "2", "2"], 1>; // expected to be '21212'
type Res3 = Join<["o"], "u">; // expected to be 'o'
// ============= Test Cases =============
import type { Equal, Expect } from './test-utils'type cases = [
  Expect<Equal<Join<['a', 'p', 'p', 'l', 'e'], '-'>, 'a-p-p-l-e'>>,
  Expect<Equal<Join<['Hello', 'World'], ' '>, 'Hello World'>>,
  Expect<Equal<Join<['2', '2', '2'], 1>, '21212'>>,
  Expect<Equal<Join<['o'], 'u'>, 'o'>>,
  Expect<Equal<Join<[], 'u'>, ''>>,
]
​
​
// ============= Your Code Here =============type Join<T extends string[], U extends string | number> = T extends [infer F  extends string, ...infer R  extends string[]]
  ? R extends []
    ? F
    : `${F}${U}${Join<R, U>}`
  : ''
​
​

首先还是需要约束泛型,第一个泛型 T 为字符串组成的数组,第二个泛型为连接符,观察发现为 number|string 这里一个个取出元素,并且在中间加上第二个泛型参数,可以想到 ${F}${U}${Join<R, U>} ,后面的元素继续递归添加第二个泛型,由此可以写出

type Join<T extends string[], U extends string | number> = T extends [infer F  extends string, ...infer R  extends string[]]
  ?  `${F}${U}${Join<R, U>}`
  : ''type aa= Join<['a', 'p', 'p', 'l', 'e'], '-'>
type aa = "a-p-p-l-e-"

这里我们会发现一堆报错,原因是我们没有判断是否是最后一个元素,如果是最后一个元素,那么就不应该拼接第二个泛型参数了,判断是不是最后一个元素很简单,你可以判断是否是空数组或者数组的长度是不是0

R['length'] extends 0
//或者
R extends []

如果是空数组,则直接返回 F即可,因为现在的 F就是最后一个元素。