持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第27天,点击查看活动详情
1. 引言
接着上一节中,接下来我们继续Ts中等篇的题型练习
https://github.com/type-challenges/type-challenges/blob/main/README.zh-CN.md 提供的TypeScript 类型体操姿势合集题型,目的是为了让大家更好的了解TS的类型系统,编写自己的类型工具,或者单纯的享受挑战的乐趣!
2. 题型
- Capitalize:实现 Capitalize 它将字符串的第一个字母转换为大写,其余字母保持原样。
type capitalized = Capitalize<'hello world'> // expected to be 'Hello world'
思路: 使用模板字面量配合infer关键字和extends判断推导到需要大写的字符串,是最后使用Uppercase 内置操作符方法把需要大写的字符串大写后在此拼接。 解答:
type MyCapitalize<S extends string> = S extends `${infer F}${infer O}` ? `${Uppercase<F>}${O}`: ''
type Demo = MyCapitalize<'foobar'> // type Demo = "Foobar"
type Demo2 = MyCapitalize<'FOOBAR'> // type Demo2 = "FOOBAR"
type Demo3 = MyCapitalize<'foo bar'> // type Demo3 = "Foo bar"
type Demo4 = MyCapitalize<''> // type Demo4 = ""
type Demo5 = MyCapitalize<'a'> // type Demo5 = "A"
type Demo6 = MyCapitalize<'b'> // type Demo6 = "B"
type Demo7 = MyCapitalize<'c'> // type Demo7 = "C"
- Replace:实现 Replace<S, From, To> 将字符串 S 中的第一个子字符串 From 替换为 To 。
type replaced = Replace<'types are fun!', 'fun', 'awesome'> // 期望是 'types are awesome!'
思路: 首先明白题意重点将字符串 S 中的第一个子字符串替换,看题意先过过滤当过滤字符串为空时,字符串S直接返回,接下来,确认被替换字符串From在字符串中出现的位置,通过模板字面量结合infer 关键字推导From处在中间位,替换为替换类型,完成。 解答:
type Replace<S extends string, From extends string, To extends string> = From extends '' ? S : S extends `${infer M}${From}${infer N}` ? `${M}${To}${N}` : S
type Demo = Replace<'foobar', 'bar', 'foo'> // type Demo = "foofoo"
type Demo2 = Replace<'foobarbar', 'bar', 'foo'> // type Demo2 = "foofoobar"
type Demo3 = Replace<'foobarbar', '', 'foo'> // type Demo3 = "foobarbar"
type Demo4 = Replace<'foobarbar', 'bar', ''> // type Demo4 = "foobar"
type Demo5 = Replace<'foobarbar', 'bra', 'foo'> // type Demo5 = "foobarbar"
type Demo6 = Replace<'', '', ''> // type Demo6 = ""
- ReplaceAll:实现 ReplaceAll<S, From, To> 将一个字符串 S 中的所有子字符串 From 替换为 To。
type replaced = ReplaceAll<'t y p e s', ' ', ''> // 期望是 'types'
思路:
与上一题场景类似,只是在最后部分,因为需求**所有子字符串 From 替换为 To**在最后使用递归操作检测后续参数是否存在需要替换字符串,如需要就执行处理。
解答:
type ReplaceAll<S extends string, From extends string, To extends string> = From extends '' ? S : S extends `${infer M}${From}${infer N}` ? `${M}${To}${ReplaceAll<N,From,To>}` : S
type Demo = ReplaceAll<'foobar', 'bar', 'foo'> // type Demo = "foofoo"
type Demo2 = ReplaceAll<'foobar', 'bag', 'foo'> // type Demo2 = "foobar"
type Demo3 = ReplaceAll<'foobarbar', 'bar', 'foo'> // type Demo3 = "foofoofoo"
type Demo4 = ReplaceAll<'t y p e s', ' ', ''> // type Demo4 = "types"
type Demo5 = ReplaceAll<'foobarbar', '', 'foo'> // type Demo5 = "foobarbar"
type Demo6 = ReplaceAll<'barfoo', 'bar', 'foo'> // type Demo6 = "foofoo"
type Demo7 = ReplaceAll<'foobarfoobar', 'ob', 'b'> // type Demo7 = "fobarfobar"
type Demo8 = ReplaceAll<'foboorfoboar', 'bo', 'b'> // type Demo8 = "foborfobar"
type Demo9 = ReplaceAll<'', '', ''> // type Demo9 = ""