type-challenges:Trim

57 阅读1分钟

Trim

问题描述

实现Trim<T>,它接受一个明确的字符串类型,并返回一个新字符串,其中两端的空白符都已被删除。

例如

type trimed = Trim<'  Hello World  '> // expected to be 'Hello World'
// ============= Test Cases =============
import type { Equal, Expect } from './test-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 '>, ''>>
]
​
// ============= Your Code Here =============
type Space = ' ' | '\n' | '\t'
type TrimLeft<S extends string> = S extends `${Space}${infer R}`
  ? TrimLeft<R>
  : S
type TrimRight<S extends string> = S extends `${infer R}${Space}`
  ? TrimRight<R>
  : S
// 答案1
type Trim<S extends string> = TrimRight<TrimLeft<S>>
type Trim<S extends string> = TrimLeft<TrimRight<S>>
​
// 答案2
type Trim<S extends string> = S extends `${Space}${infer R}`
  ? Trim<R>
  : S extends `${infer L}${Space}`
  ? Trim<L>
  : S
​
// 答案2
type Trim<S extends string> = S extends `${Space}${infer R}` | `${infer R}${Space}` ? Trim<R> : S;

有上一道题 Trim Left 的基础,这道题应该也不难,首先,我们需要找到需要排除的字符 type Space = ' ' | '\n' | '\t' ,可以先判断左边,也可以先判断右边,我们看从左边开始,如果左边的字符在当前 Space 中,则不需要这个字符,拿到 infer 后的泛型 R ,继续递归判断,直到最后会走条件判断的 false 得到 泛型S,这个泛型 S,是去除了左边所有空格和换行符的字符串,再拿当前得到的类型传入泛型 TrimRight 中,得到最后去除所有空格和换行符之后的字符串,答案2实际上是同一个意思,只是将所有的逻辑写在了一个泛型中,这里可以更简单些,即得到答案3。