[TypeScript] Type Challenges #108 - Trim

118 阅读1分钟

题目描述

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

例如

type trimed = Trim<'  Hello World  '// expected to be 'Hello World'

题解

// ============= Test Cases =============
import type { EqualExpect } 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 Whitespace = ' ' | '\n' | '\t';

type Trim<T extends string> =
  T extends `${Whitespace}${infer U}` | `${infer U}${Whitespace}`
  ? Trim<U>
  : T;

类型约束

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

条件类型

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

递归调用

Trim<U>递归调用Trim类型,继续删除两端的空白字符,直到字符串不再以空白字符开头或结尾