Replace
问题描述
实现 Replace<S, From, To> 将字符串 S 中的第一个子字符串 From 替换为 To 。
例如
type replaced = Replace<'types are fun!', 'fun', 'awesome'> // 期望是 'types are awesome!'
// ============= Test Cases =============
import type { Equal, Expect } 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 =============
// 答案1
type Replace<S extends string, From extends string, To extends string> =
S extends `${infer L}${From extends ''
? never
: From}${infer R}`
? `${L}${To}${R}`
: S
// 答案2
type Replace<S extends string, From extends string, To extends string> =
From extends ''
? S
: S extends `${infer A}${From}${infer B}`
? `${A}${To}${B}`
: S;
// 错误答案
type Replace<S extends string, From extends string, To extends string> =
S extends `${infer L}${From extends ''
? ''
: From}${infer R}`
? `${L}${To}${R}`
: S
这道题第一次见可能很难想到这种方式,Replace接受三个参数:S(源字符串),From(要替换的子字符串)和To(用于替换的新子字符串)。类型操作符的目的是将字符串S中的所有From子字符串替换为To子字符串。
实现原理:
- 使用
infer关键字定义两个类型变量L和R,它们分别表示S的左侧和右侧部分。 - 使用
extends关键字检查S是否以From结尾,如果是,则将其替换为To。 - 如果
S不是以From结尾,则保持原样。
可能有人好奇为什么 From extends ''? '': From 这样就不可以呢,因为这样就会导致中间的内容为空,泛型 L 和泛型 R 拼接到一起了。
或者也可以先排除空字符串的情况,参考答案2。