TS类型挑战题目记录-中等篇2
Trim Left
- 实现 TrimLeft
,它接收确定的字符串类型并返回一个新的字符串,其中新返回的字符串删除了原字符串开头的空白字符串。 1
2
3
4
5
6
7
8
9
10
11type TrimLeft<S extends string> = S extends `${" " | "\n" | "\t"}${infer R}` ? TrimLeft<R> : S
type cases = [
Expect<Equal<TrimLeft<'str'>, 'str'>>,
Expect<Equal<TrimLeft<' str'>, 'str'>>,
Expect<Equal<TrimLeft<' str'>, 'str'>>,
Expect<Equal<TrimLeft<' str '>, 'str '>>,
Expect<Equal<TrimLeft<' \n\t foo bar '>, 'foo bar '>>,
Expect<Equal<TrimLeft<''>, ''>>,
Expect<Equal<TrimLeft<' \n\t'>, ''>>,
]
Trim
- 实现Trim
,它是一个字符串类型,并返回一个新字符串,其中两端的空白符都已被删除。 1
2
3
4
5
6
7
8
9
10
11
12type Trim<S extends string> = S extends `${" " | "\n" | "\t"}${infer R}` | `${infer R}${" " | "\n" | "\t"}` ? Trim<R> : S
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 '>, ''>>,
]
Capitalize
- 实现 Capitalize
它将字符串的第一个字母转换为大写,其余字母保持原样。 1
2
3
4
5
6
7
8type MyCapitalize<S extends string> = S extends `${infer First}${infer Rest}` ? `${Uppercase<First>}${Rest}` : S
Expect<Equal<MyCapitalize<'foobar'>, 'Foobar'>>,
Expect<Equal<MyCapitalize<'FOOBAR'>, 'FOOBAR'>>,
Expect<Equal<MyCapitalize<'foo bar'>, 'Foo bar'>>,
Expect<Equal<MyCapitalize<''>, ''>>,
Expect<Equal<MyCapitalize<'a'>, 'A'>>,
Expect<Equal<MyCapitalize<'b'>, 'B'>>,
Replace
- 实现 Replace<S, From, To> 将字符串 S 中的第一个子字符串 From 替换为 To 。
1
2
3
4
5
6
7
8
9
10type Replace<S extends string, From extends string, To extends string> = S extends `${infer A}${From}${infer B}` ? From extends '' ? S :`${A}${To}${B}` : S
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<'', '', ''>, ''>>,
]
ReplaceAll
- 实现 ReplaceAll<S, From, To> 将一个字符串 S 中的所有子字符串 From 替换为 To。
1
2
3
4
5
6
7
8
9
10
11
12
13type ReplaceAll<S extends string, From extends string, To extends string> = S extends `${infer A}${From}${infer B}` ? From extends '' ? S : `${A}${To}${ReplaceAll<B, From, To>}` : S
type cases = [
Expect<Equal<ReplaceAll<'foobar', 'bar', 'foo'>, 'foofoo'>>,
Expect<Equal<ReplaceAll<'foobar', 'bag', 'foo'>, 'foobar'>>,
Expect<Equal<ReplaceAll<'foobarbar', 'bar', 'foo'>, 'foofoofoo'>>,
Expect<Equal<ReplaceAll<'t y p e s', ' ', ''>, 'types'>>,
Expect<Equal<ReplaceAll<'foobarbar', '', 'foo'>, 'foobarbar'>>,
Expect<Equal<ReplaceAll<'barfoo', 'bar', 'foo'>, 'foofoo'>>,
Expect<Equal<ReplaceAll<'foobarfoobar', 'ob', 'b'>, 'fobarfobar'>>,
Expect<Equal<ReplaceAll<'foboorfoboar', 'bo', 'b'>, 'foborfobar'>>,
Expect<Equal<ReplaceAll<'', '', ''>, ''>>,
]
Append Argument
- 实现一个泛型 AppendArgument<Fn, A>,对于给定的函数类型 Fn,以及一个任意类型 A,返回一个新的函数 G。G 拥有 Fn 的所有参数并在末尾追加类型为 A 的参数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17type AppendArgument<Fn extends Function, A extends unknown> = Fn extends (...args: infer T) => infer U
? (...args: [...T, A]) => U
: Fn
type Case1 = AppendArgument<(a: number, b: string) => number, boolean>
type Result1 = (a: number, b: string, x: boolean) => number
type Case2 = AppendArgument<() => void, undefined>
type Result2 = (x: undefined) => void
type cases = [
Expect<Equal<Case1, Result1>>,
Expect<Equal<Case2, Result2>>,
// @ts-expect-error
AppendArgument<unknown, undefined>,
]
Permutation
- 实现联合类型的全排列,将联合类型转换成所有可能的全排列数组的联合类型。
1
2
3
4
5
6
7
8
9
10
11
12
13type Permutation<T, Acc = T> = [T] extends [never]
? []
: Acc extends T
? [Acc, ...Permutation<Exclude<T, Acc>>]
: []
type cases = [
Expect<Equal<Permutation<'A'>, ['A']>>,
Expect<Equal<Permutation<'A' | 'B' | 'C'>, ['A', 'B', 'C'] | ['A', 'C', 'B'] | ['B', 'A', 'C'] | ['B', 'C', 'A'] | ['C', 'A', 'B'] | ['C', 'B', 'A']>>,
Expect<Equal<Permutation<'B' | 'A' | 'C'>, ['A', 'B', 'C'] | ['A', 'C', 'B'] | ['B', 'A', 'C'] | ['B', 'C', 'A'] | ['C', 'A', 'B'] | ['C', 'B', 'A']>>,
Expect<Equal<Permutation<boolean>, [false, true] | [true, false]>>,
Expect<Equal<Permutation<never>, []>>,
]
Length of String
- 计算字符串的长度,类似于 String#length
1
2
3
4
5
6
7
8
9
10
11type
type LengthOfString<S extends string, Acc extends string[] = []
> = S extends `${infer Head}${infer Tail}`
? LengthOfString<Tail, [...Acc, Head]> : Acc['length']
type cases = [
Expect<Equal<LengthOfString<''>, 0>>,
Expect<Equal<LengthOfString<'kumiko'>, 6>>,
Expect<Equal<LengthOfString<'reina'>, 5>>,
Expect<Equal<LengthOfString<'Sound! Euphonium'>, 16>>,
]
Flatten
- 写一个接受数组的类型,并且返回扁平化的数组类型
1
2
3
4
5
6
7
8
9type Flatten<T extends any[]> = T extends [infer F, ... infer R] ? F extends unknown[] ? [...Flatten<F>, ...Flatten<R>] : [F, ...Flatten<R>] : []
type cases = [
Expect<Equal<Flatten<[]>, []>>,
Expect<Equal<Flatten<[1, 2, 3, 4]>, [1, 2, 3, 4]>>,
Expect<Equal<Flatten<[1, [2]]>, [1, 2]>>,
Expect<Equal<Flatten<[1, 2, [3, 4], [[[5]]]]>, [1, 2, 3, 4, 5]>>,
Expect<Equal<Flatten<[{ foo: 'bar'; 2: 10 }, 'foobar']>, [{ foo: 'bar'; 2: 10 }, 'foobar']>>,
]
Append to object
- 实现一个为接口添加一个新字段的类型。该类型接收三个参数,返回带有新字段的接口类型。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44type AppendToObject<T extends Object, U extends PropertyKey, V> = { [key in (keyof T | U)]: key extends keyof T ? T[key] : V }
type test1 = {
key: 'cat'
value: 'green'
}
type testExpect1 = {
key: 'cat'
value: 'green'
home: boolean
}
type test2 = {
key: 'dog' | undefined
value: 'white'
sun: true
}
type testExpect2 = {
key: 'dog' | undefined
value: 'white'
sun: true
home: 1
}
type test3 = {
key: 'cow'
value: 'yellow'
sun: false
}
type testExpect3 = {
key: 'cow'
value: 'yellow'
sun: false
isMotherRussia: false | undefined
}
type cases = [
Expect<Equal<AppendToObject<test1, 'home', boolean>, testExpect1>>,
Expect<Equal<AppendToObject<test2, 'home', 1>, testExpect2>>,
Expect<Equal<AppendToObject<test3, 'isMotherRussia', false | undefined>, testExpect3>>,
]
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 随心所欲录!
评论