[TypeScript] Type Challenges #106 - Trim Left

69 阅读1分钟

题目描述

实现TrimLeft<T> ,它接收确定的字符串类型并返回一个新的字符串,其中新返回的字符串删除了原字符串开头的空白字符串。

例如

type trimed = TrimLeft<'  Hello World  '// 应推导出 'Hello World  '

题解

// ============= Test Cases =============
import type { EqualExpect } from './test-utils'

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


// ============= Your Code Here =============
type Whitespace = ' ' | '\n' | '\t';
type TrimLeft<S extends string> =
  S extends `${Whitespace}${infer U}`
      ? TrimLeft<U>
      : S;

类型约束

使用S extends string对类型S进行约束,确保S是一个字符串类型

条件类型

extends `${Whitespace}${infer U}` ? TrimLeft<U> : S
  • S extends ${Whitespace}${infer U}:这是一个条件类型,检查S是否以空白字符开头
    • Whitespace是一个联合类型,包含了常见的空白字符:' ''\n''\t'
    • infer U用于推断出S中除去开头的空白字符后的剩余部分
  • 如果S以空白字符开头,则递归调用TrimLeft<U>对剩余部分U继续进行修剪操作
  • 如果S不以空白字符开头,则返回S本身

递归调用

TrimLeft<U>:递归调用TrimLeft类型,继续删除开头的空白字符,直到字符串不再以空白字符开头