Skip to content

Commit 8298c07

Browse files
✨ add medium topic and fix some style
1 parent 6822c3b commit 8298c07

File tree

7 files changed

+2197
-26
lines changed

7 files changed

+2197
-26
lines changed

docs/challenges/easy/awaited.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ title: 实现Awaited
44

55
# {{ $frontmatter.title }}
66

7-
## 题目描述
7+
## 🎯 题目描述
88

99
假如我们有一个 Promise 对象,这个 Promise 对象会返回一个类型。在 TS 中,我们用 `Promise<T>` 中的 T 来描述这个 Promise 返回的类型。请你实现一个类型,可以获取这个类型。
1010

@@ -16,7 +16,7 @@ type ExampleType = Promise<string>;
1616
type Result = MyAwaited<ExampleType>; // string
1717
```
1818

19-
## 分析
19+
## 🔍 分析
2020

2121
```ts
2222
type MyAwaited<T> = T extends Promise<infer R> ? R : never;
@@ -41,7 +41,7 @@ type Case2 = MyAwaited<Promise<Promise<string>>>; // string
4141
type Case3 = MyAwaited<Promise<Promise<Promise<string>>>>; // string
4242
```
4343

44-
## 题解
44+
## 🛠️ 题解
4545

4646
在题目的 Case 中,存在如下场景:
4747

@@ -65,7 +65,7 @@ type MyAwaited<T> = T extends
6565

6666
这里还有一点值得一提的是,当联合类型位于 `extends` 右侧时,并没有分发特性,虽然判断会做多次,但是其多次判断的结果会以或的方式合并后交由 `extends` 的逻辑处理,比如,`'a' extends 'a' | 'b' ? 1 : 2`,此时,可以理解为会进行 `'a' extends 'a'` 以及 `'a' extends 'b'`两次判断,两者有一处为 true 即返回 1,否则返回 2。但是并不会返回 `1 | 2`
6767

68-
## 知识点
68+
## 💡 知识点
6969

7070
1. `A extends Promise<infer R>`,匹配推断类型
7171
2. 递归解决嵌套问题

docs/challenges/easy/index.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ title: 实现Readonly
44

55
# {{ $frontmatter.title }}
66

7-
## 题目描述
7+
## 🎯 题目描述
88

99
不要使用内置的 `Readonly<T>`,自己实现一个。
1010

@@ -29,7 +29,7 @@ todo.title = 'Hello'; // Error: cannot reassign a readonly property
2929
todo.description = 'barFoo'; // Error: cannot reassign a readonly property
3030
```
3131

32-
## 分析
32+
## 🔍 分析
3333

3434
这一题,本质也是对对象类型进行遍历,然后为每一个属性增加 `readonly` 的修饰符,只需要在遍历的时候为每一个属性增加只读修饰符。
3535

@@ -39,15 +39,15 @@ type MyReadonly<T> = {
3939
};
4040
```
4141

42-
## 题解
42+
## 🛠️ 题解
4343

4444
```ts
4545
type MyReadonly<T> = {
4646
readonly [P in keyof T]: T[P];
4747
};
4848
```
4949

50-
## 知识点
50+
## 💡 知识点
5151

5252
1. `[P in keyof T]` 遍历 对象类型(数组也是对象)
5353
2. `readonly` 增加修饰符即可

docs/challenges/easy/paramEters.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ title: 实现Parameters
44

55
# {{ $frontmatter.title }}
66

7-
## 题目描述
7+
## 🎯 题目描述
88

99
实现内置的 `Parameters<T>` 类型,而不是直接使用它。
1010

@@ -17,7 +17,7 @@ const foo = (arg1: string, arg2: number): void => {};
1717
type FunctionParamsType = MyParameters<typeof foo>;
1818
```
1919

20-
## 分析
20+
## 🔍 分析
2121

2222
使用 `A extends infer B` 这样的匹配推断,不过这里推断的是函数的参数。可以先从一个参数推断开始:
2323

@@ -39,15 +39,15 @@ type Case2 = MyFirstParameter<() => {}>;
3939

4040
可以通过扩展操作符进行。
4141

42-
## 题解
42+
## 🛠️ 题解
4343

4444
```ts
4545
type Parameters<T extends (...args: any) => any> =
4646
// 扩展操作符,推断出 P
4747
T extends (...args: infer P) => any ? P : never;
4848
```
4949

50-
## 知识点
50+
## 💡 知识点
5151

5252
1. 函数类型,也可以做推断匹配,`A extends (...args: infer P) => infer R`
5353
2. 函数类型,推断匹配时,使用扩展操作符

docs/challenges/easy/pick.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ title: 实现Pick
44

55
# {{ $frontmatter.title }}
66

7-
## 题目描述
7+
## 🎯 题目描述
88

99
实现 TS 内置的 `Pick<T, K>`,但不可以使用它。
1010

@@ -27,7 +27,7 @@ const todo: TodoPreview = {
2727
};
2828
```
2929

30-
## 分析
30+
## 🔍 分析
3131

3232
此题的核心在于对 对象类型 的遍历并修改,对 对象类型的遍历方法如下:
3333

@@ -42,14 +42,14 @@ type Case1 = Copy<{ a: string; b: string }>;
4242
`keyof T` 本身是个联合类型,`[P in keyof T]` 便是将联合类型取出作为新类型的键值, 在上例中,流程如下:
4343

4444
```ts
45-
// step1: keyof T: 'a' | 'b'
46-
// ['a']: T['a'] (也就是 string)
45+
// 💡 step1: keyof T: 'a' | 'b'
46+
// 💡 ['a']: T['a'] (也就是 string)
4747
// ['b']: T['b'] (也就是 string)
4848
// type Case1 = { a: string, b: string }
4949
type Case1 = Copy<{ a: 1; b: 2 }>;
5050
```
5151

52-
## 题解
52+
## 🛠️ 题解
5353

5454
理解了上述遍历的行为后,实现 `Pick` 就非常简单了,只需要把 `keyof T` 这个联合类型换成入参的 `K` 即可:
5555

@@ -67,7 +67,7 @@ type Case2 = MyPick<{ a: string; b: string; c: string }, 'a' | 'b'>;
6767

6868
注意:上述需要对 `K` 进行约束,也就是 `K extends keyof T`,因为 K 如果不是类型的键值的话,需要进行类型约束,否则 `T[P]` 将会因为访问不到类型而报错。
6969

70-
## 知识点
70+
## 💡 知识点
7171

7272
1. `[P in keyof T]: T[P]` 遍历 对象类型/数组类型
7373
2. `[P in K]: T[P]` ,根据传入的 K 进行遍历,此时 K 需要满足 `K extends keyof T`

docs/challenges/easy/readonly.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ title: 实现Readonly
44

55
# {{ $frontmatter.title }}
66

7-
## 题目描述
7+
## 🎯 题目描述
88

99
不要使用内置的 `Readonly<T>`,自己实现一个。
1010

@@ -29,7 +29,7 @@ todo.title = 'Hello'; // Error: cannot reassign a readonly property
2929
todo.description = 'barFoo'; // Error: cannot reassign a readonly property
3030
```
3131

32-
## 分析
32+
## 🔍 分析
3333

3434
这一题,本质也是对对象类型进行遍历,然后为每一个属性增加 `readonly` 的修饰符,只需要在遍历的时候为每一个属性增加只读修饰符。
3535

@@ -39,15 +39,15 @@ type MyReadonly<T> = {
3939
};
4040
```
4141

42-
## 题解
42+
## 🛠️ 题解
4343

4444
```ts
4545
type MyReadonly<T> = {
4646
readonly [P in keyof T]: T[P];
4747
};
4848
```
4949

50-
## 知识点
50+
## 💡 知识点
5151

5252
1. `[P in keyof T]` 遍历 对象类型(数组也是对象)
5353
2. `readonly` 增加修饰符即可

docs/challenges/easy/tuples.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ title: 元组转换为对象
44

55
# {{ $frontmatter.title }}
66

7-
## 题目描述
7+
## 🎯 题目描述
88

99
传入一个元组类型,将这个元组类型转换为对象类型,这个对象类型的键/值都是从元组中遍历出来。
1010

@@ -18,7 +18,7 @@ const tuple = ['tesla', 'model 3', 'model X', 'model Y'] as const;
1818
type result = TupleToObject<typeof tuple>;
1919
```
2020

21-
## 分析
21+
## 🔍 分析
2222

2323
此题目标是生成一个新的对象类型,其键值和属性值就是传入的元组的每一项的值,在前面的题目中我们了解了遍历一个对象的方法,加以改动,就可以改为生成一个对象的方法,如下,给定一个联合类型 `'a' | 'b'`,生成一个新的对象:
2424

@@ -64,7 +64,7 @@ type MyArrayLike<T> = {
6464
type Case3 = ArrayLike<string>[number];
6565
```
6666

67-
## 题解
67+
## 🛠️ 题解
6868

6969
了解了元组转为联合类型的方法后,答案也就呼之欲出了:
7070

@@ -76,6 +76,6 @@ type TupleToObject<T extends readonly PropertyKey[]> = {
7676

7777
这里也是,需要对输入的元组进行类型限制,其元素必须是 `PropertyKey`(ts 内置类型: `type PropertyKey = string | number | symbol`)。
7878

79-
## 知识点
79+
## 💡 知识点
8080

8181
1. `T[number]` 索引签名访问,元组转联合类型

0 commit comments

Comments
 (0)