typescript 类型体操 之 108-medium-trim

298 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第18天,点击查看活动详情

前言

在学习typescript的过程当中,有一个github库对其类型的学习特别有帮助,是一个有点类似于leetcode的刷题项目,能够在里面刷各种关于typescript类型的题目,在上一篇文章中,我们完成了中等的第十一题,今天来做中等的第十二题 108-medium-trim

下面这个是类型体操github仓库:

type-challenges/type-challenges: Collection of TypeScript type challenges with online judge (github.com)

108-medium-trim

image.png

import type { Equal, Expect } from '@type-challenges/utils'

type cases = [
  Expect<Equal<Trim<'str'>, 'str'>>,
  Expect<Equal<Trim<' str'>, 'str'>>,
  Expect<Equal<Trim<'     str'>, 'str'>>,
  Expect<Equal<Trim<'str   '>, 'str'>>,
  Expect<Equal<Trim<'     str     '>, 'str'>>,
  Expect<Equal<Trim<'   \n\t foo bar \t'>, 'foo bar'>>,
  Expect<Equal<Trim<''>, ''>>,
  Expect<Equal<Trim<' \n\t '>, ''>>,
]

从README和测试用例中能够得出,我们需要实现一个工具函数 Trim 能够去掉字符串两边的 空格或者 \n\t,算是昨天的 TrimLeft 的升级版本。

通过 JS 对比学习

我们需要实现一个函数,将传入的字符串前面和后面的空格或者 \n\t 进行删除。

今天我们采用递归的思路来进行删除,首先判断字符串前面的第一位是否是三种情况,是的话就把去掉第一个字符的剩余部分再次丢入函数,然后判断字符串的后面是不是这三种情况,是的话就把前面的部分丢入这个函数,如果前面和后面都不是这三种情况的话,那么就说明已经清除完成了。

function trim(str: string): string {
  if(str[0] == " " || str[0] == "\n" || str[0] == "\t"){
    return trim(str.slice(1,str.length))
  }
  if(str[str.length-1] == " " || str[str.length-1] == "\n" || str[str.length-1] == "\t"){
    return trim(str.slice(0,str.length-1))
  }
  return str
}

image.png

实现 TrimLeft

通过 JS 的实现思路,我们也能够通过模板字面量去去除前面或者后面的字符,以及递归来进行多次的删除,只不过是需要判断前面以及后面两个位置罢了。

和昨天一样的,我们可以优先定义一个联合类型用于表示三种情况:

type TrimWord = " " | "\n" | "\t";

然后就是昨日的思路来进行前面的删除,并且后面的部分也是一样的,只是需要添加一层条件链:

type TrimWord = " " | "\n" | "\t";

type Trim<S extends string> = S extends `${infer R1}${TrimWord}`
  ? Trim<R1>
  : S extends `${TrimWord}${infer R2}`
    ? Trim<R2>
    : S 

这样我们的测试case就能够全部通过了,今天这道题和昨天的完全是一样的,这里就不做过多的讲解。

知识点

关于上述提到了部分的知识点:

  1. 模板字面量
  2. infer 关键字
  3. 条件链

模板字面量在之前的文章中我们有做过简单的介绍,并且昨天也有使用,可以通过另外一篇文章了解一下模板字面量的一个基础特点。

TypeScript 之 模板字面量 - 掘金 (juejin.cn)

总结

今天我们做完了中等的第十二题,题型和昨天的是完全一样的,只能算是昨天的升级版本,通过昨天的知识就能够很轻松的完成今天的这道题。