一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第23天,点击查看活动详情。
题目三十四:remove-index-signature
// template.ts
type RemoveIndexSignature<T> = any
// test-cases.ts
import type { Equal, Expect } from '@type-challenges/utils'
type Foo = {
[key: string]: any
foo(): void
}
type Bar = {
[key: number]: any
bar(): void
}
type FooBar = {
[key: symbol]: any
foobar(): void
}
type Baz = {
bar(): void
baz: string
}
type cases = [
Expect<Equal<RemoveIndexSignature<Foo>, { foo(): void }>>,
Expect<Equal<RemoveIndexSignature<Bar>, { bar(): void }>>,
Expect<Equal<RemoveIndexSignature<FooBar>, { foobar(): void }>>,
Expect<Equal<RemoveIndexSignature<Baz>, { bar(): void; baz: string }>>,
]
实现“RemoveIndexSignature”,从对象类型中排除索引签名(类似:[key: string]: any)。
代码实现
- 原代码
type RemoveIndexSignature<T> = any
- 遍历传入的参数
T
type RemoveIndexSignature<T> = {
[P in keyof T]: T[P]
}
- 将键值
P放入字符串中,判断是否和原先的内容相同(索引签名不是字符串)
type RemoveIndexSignature<T> = {
[P in keyof T as P extends `${infer R}` ? R : never]: T[P]
}
题目三十五:percentage-parser
// template.ts
type PercentageParser<A extends string> = any
// test-cases.ts
import type { Equal, Expect } from '@type-challenges/utils'
type Case0 = ['', '', '']
type Case1 = ['+', '', '']
type Case2 = ['+', '1', '']
type Case3 = ['+', '100', '']
type Case4 = ['+', '100', '%']
type Case5 = ['', '100', '%']
type Case6 = ['-', '100', '%']
type Case7 = ['-', '100', '']
type Case8 = ['-', '1', '']
type Case9 = ['', '', '%']
type Case10 = ['', '1', '']
type Case11 = ['', '100', '']
type cases = [
Expect<Equal<PercentageParser<''>, Case0>>,
Expect<Equal<PercentageParser<'+'>, Case1>>,
Expect<Equal<PercentageParser<'+1'>, Case2>>,
Expect<Equal<PercentageParser<'+100'>, Case3>>,
Expect<Equal<PercentageParser<'+100%'>, Case4>>,
Expect<Equal<PercentageParser<'100%'>, Case5>>,
Expect<Equal<PercentageParser<'-100%'>, Case6>>,
Expect<Equal<PercentageParser<'-100'>, Case7>>,
Expect<Equal<PercentageParser<'-1'>, Case8>>,
Expect<Equal<PercentageParser<'%'>, Case9>>,
Expect<Equal<PercentageParser<'1'>, Case10>>,
Expect<Equal<PercentageParser<'100'>, Case11>>,
]
实现PercentageParser <T extends string>。
根据/^(\+\\-)?(\d*)?(\%)?$/ 规律性匹配T并获得三个匹配。
结构应该是:[‘正负’、‘数字’、‘单位`]
如果未捕获,则默认为空字符串。
代码实现
- 原代码
type PercentageParser<A extends string> = any
- 设计函数
MatchSymbol,功能:从字符串中抽取符号
type MatchSymbol<T> = T extends `${infer F}${infer _}`
? F extends '+' | '-'
? F
: ''
: ''
- 设计函数
MatchUnit,功能:从字符串中抽取单位
type MatchUnit<T> = T extends `${infer _}%` ? '%' : ''
- 设计函数
MatchValue,功能:从字符串中抽取数值
type MatchValue<T> = T extends `${MatchSymbol<T>}${infer V}${MatchUnit<T>}` ? V : ''
- 最后实现
PercentageParser
type PercentageParser<A extends string> = [MatchSymbol<A>, MatchValue<A>, MatchUnit<A>]
题目三十六:drop-char
// template.ts
type DropChar<S, C> = any
// test-cases
import type { Equal, Expect } from '@type-challenges/utils'
type cases = [
// @ts-expect-error
Expect<Equal<DropChar<'butter fly!', ''>, 'butterfly!'>>,
Expect<Equal<DropChar<'butter fly!', ' '>, 'butterfly!'>>,
Expect<Equal<DropChar<'butter fly!', '!'>, 'butter fly'>>,
Expect<Equal<DropChar<' butter fly! ', ' '>, 'butterfly!'>>,
Expect<Equal<DropChar<' b u t t e r f l y ! ', ' '>, 'butterfly!'>>,
Expect<Equal<DropChar<' b u t t e r f l y ! ', 'b'>, ' u t t e r f l y ! '>>,
Expect<Equal<DropChar<' b u t t e r f l y ! ', 't'>, ' b u e r f l y ! '>>,
]
从字符串中删除指定的字符。
代码实现
- 原代码
type DropChar<S, C> = any
- 传入的两个参数都是
string类型
type DropChar<S extends string, C extends string> = any
- 将
S进行拆分,看看能不能拆出包含C的字符串
type DropChar<S extends string, C extends string> = S extends `${infer First}${C}${infer Last}`
? ...
: ...
- 如果没拆出来,说明
S中已经没有C了,则直接返回
type DropChar<S extends string, C extends string> = S extends `${infer First}${C}${infer Last}`
? ...
: S
- 如果拆出来了,则去除掉当前的字符串
C,递归调用DropChar方法
type DropChar<S extends string, C extends string> = S extends `${infer First}${C}${infer Last}`
? DropChar<`${First}${Last}`, C>
: S