[TypeScript] Type Challenges #116 - Replace

75 阅读1分钟

题目描述

实现Replace<S, From, To>将字符串S中的第一个子字符串From替换为To

例如

type replaced = Replace<'types are fun!''fun''awesome'// 期望是 'types are awesome!'

题解

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

type cases = [
  Expect<Equal<Replace<'foobar''bar''foo'>, 'foofoo'>>,
  Expect<Equal<Replace<'foobarbar''bar''foo'>, 'foofoobar'>>,
  Expect<Equal<Replace<'foobarbar''''foo'>, 'foobarbar'>>,
  Expect<Equal<Replace<'foobarbar''bar'''>, 'foobar'>>,
  Expect<Equal<Replace<'foobarbar''bra''foo'>, 'foobarbar'>>,
  Expect<Equal<Replace<''''''>, ''>>,
]


// ============= Your Code Here =============
type Replace<T extends stringFrom extends stringTo extends string> = 
    From extends ''
      ? T
      : T extends `${infer L}${From}${infer R}`
          ? `${L}${To}${R}`
          : T;

类型约束

使用T extends string对类型T进行约束,确保T是一个字符串类型。同样,对FromTo也进行相同的约束,确保它们都是字符串类型

条件类型

type Replace<T extends stringFrom extends stringTo extends string> = 
    From extends ''
      ? T
      : T extends `${infer L}${From}${infer R}`
          ? `${L}${To}${R}`
          : T;
  • From extends ''检查From是否为空字符串
    • 如果From是空字符串,直接返回T
  • T extends ${infer L}${From}${infer R} ?${L}${To}${R} : T
    • infer L用于推断出TFrom之前的部分
    • infer R用于推断出TFrom之后的部分
    • 如果T中包含From,则将From替换为To,并拼接LR
    • 如果T不包含From,则返回T本身