Skip to content

Commit 289663c

Browse files
author
febobo
committed
update h.md
1 parent 918b217 commit 289663c

File tree

4 files changed

+228
-20
lines changed

4 files changed

+228
-20
lines changed

docs/es6/typeScript.md

Lines changed: 225 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,163 @@
1-
### 概述
1+
### 初次见面
2+
官方对其只用了一句话来描述
3+
> TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. Any browser. Any host. Any OS. Open source.
4+
5+
大致意思为,TypeScript 是开源的,TypeScript 是 JavaScript 的类型的**超集**,它可以编译成纯 JavaScript。编译出来的 JavaScript 可以运行在任何浏览器上。TypeScript 编译工具可以运行在任何服务器和任何系统上
6+
7+
* 问题1: 什么是超集
8+
9+
**超集是集合论的术语**
10+
说到超集,不得不说另一个,子集,怎么理解这两个概念呢,举个例子
11+
12+
如果一个集合A里面的的所有元素集合B里面都存在,那么我们可以理解集合A是集合B的超集,反之集合B为集合A的子集
13+
14+
现在我们就能理解为 `Typescript` 里包含了 `Javascript` 的所有特性,这也意味着我们可以将`.js`后缀直接命名为`.ts`文件跑到`TypeScript`的编绎系统中
15+
16+
### Typescript 解决了什么问题
17+
18+
**一个事物的诞生一定会有其存在的价值**
19+
20+
那么 `Typescript` 的价值是什么呢?
21+
22+
回答这个问题之前,我们有必要先来了解一下 `Typescript` 的工作理念
23+
24+
本质上是在 `JavaScript` 上增加一套**静态类型系统**(编译时进行类型分析),强调静态类型系统是为了和运行时的类型检查机制做区分,`TypeScript` 的代码最终会被编译为 `JavaScript`
25+
26+
我们再回到问题本身,缩小一下范围,`Typescript` 创造的价值大部分是在开发时体现的(编译时),而非运行时,如
27+
28+
- 强大的编辑器智能提示 (研发效率,开发体验)
29+
- 代码可读性增强 (团队协作,开发体验)
30+
- 编译时类型检查 (业务稳健,前端项目中Top10 的错误类型低级的类型错误占比达到70%)
31+
32+
### 正文
33+
34+
本篇文章作为 `Vue3` 源码系列前置篇章之一,`Typescript` 的科普文,主要目的为了大家在面对 `Vue3` 源码时不会显得那么不知所措,下来将介绍一些 `Typescript` 的基本使用
235

336
### 变量申明
37+
38+
#### 基本类型
439
```js
40+
let isDone: boolean = false
541
let num: number = 1
6-
let str: string = 'hello'
42+
let str: string = 'vue3js.cn'
43+
let arr: number[] = [1, 2, 3]
44+
let arr2: Array<number> = [1, 2, 3] // 泛型数组
45+
let obj: Object = {}
46+
let u: undefined = undefined;
47+
let n: null = null;
748
```
849

9-
### 函数参数类型与返回值类型
50+
#### 类型补充
51+
52+
- 枚举 `Enum`,使用枚举类型可以为一组数值赋予友好的名字
1053
```js
11-
function sum(a: number, b: number): number {
12-
return a + b
54+
enum LogLevel {
55+
info = 'info',
56+
warn = 'warn',
57+
error = 'error',
1358
}
1459
```
15-
### 复合元素类型
60+
61+
- 元组 `Tuple` 允许数组各元素的类型不必相同。 比如,你可以定义一对值分别为 string和number类型的元组
62+
1663
```js
17-
let arr: Array<number> = [1, 2, 3]
18-
let set: Set<number> = new Set([1, 2, 2])
19-
let map: Map<string, number> = new Map([['key1', 1], ['key2', 2]])
64+
// Declare a tuple type
65+
let x: [string, number];
66+
// Initialize it
67+
x = ['hello', 10]; // OK
68+
// Initialize it incorrectly
69+
x = [10, 'hello']; // Error
2070
```
21-
### 接口类型
71+
72+
- 任意值 `Any` 表示任意类型,通常用于不确定内容的类型,比如来自用户输入或第三方代码库
73+
74+
```js
75+
let notSure: any = 4;
76+
notSure = "maybe a string instead";
77+
notSure = false; // okay, definitely a boolean
78+
```
79+
- 空值 `Void` 与 any 相反,通常用于函数,表示没有返回值
80+
81+
```js
82+
function warnUser(): void {
83+
console.log("This is my warning message");
84+
}
85+
```
86+
87+
- 接口 `interface` 类型契约,跟我们平常调服务端接口要先定义字段一个理
88+
89+
如下例子 point 跟 Point 类型必须一致,多一个少一个也是不被允许的
2290
```js
2391
interface Point {
2492
x: number
2593
y: number
94+
z?: number
95+
readonly l: number
2696
}
27-
const point: Point = { x: 10, y: 20 }
97+
const point: Point = { x: 10, y: 20, z: 30, l: 40 }
98+
const point2: Point = { x: '10', y: 20, z: 30, l: 40 } // Error
99+
const point3: Point = { x: 10, y: 20, z: 30 } // Error
100+
const point4: Point = { x: 10, y: 20, z: 30, l: 40, m: 50 } // Error
101+
28102
```
29-
### 类型别名
103+
104+
可选与只读 ? 表示可选参, readonly 表示只读
105+
30106
```js
31-
type mathfunc = (a: number, b: number) => number
32-
const product: mathfunc = (a, b) => a * b
107+
const point5: Point = { x: 10, y: 20, l: 40 } // 正常
108+
point5.l = 50 // error
109+
```
110+
111+
### 函数参数类型与返回值类型
112+
113+
```js
114+
function sum(a: number, b: number): number {
115+
return a + b
116+
}
117+
```
118+
119+
配合 `interface` 使用
120+
121+
```js
122+
interface Point {
123+
x: number
124+
y: number
125+
}
126+
127+
function sum({ x, y}: Point): number {
128+
return x + y
129+
}
130+
131+
sum({x:1, y:2}) // 3
33132
```
34133

35134
### 泛型
36-
泛型的意义在于函数的重用性,我们希望组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型
135+
泛型的意义在于函数的重用性,设计原则希望组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型
136+
137+
* 比如
37138

38-
**为什么不用`any`呢?**
139+
根据业务最初的设计函数 `identity` 入参为`String`
140+
```js
141+
function identity(arg: String){
142+
return arg
143+
}
144+
console.log(identity('100'))
145+
```
146+
147+
业务迭代过程参数需要支持 `Number`
148+
```js
149+
function identity(arg: String){
150+
return arg
151+
}
152+
console.log(identity(100)) // Argument of type '100' is not assignable to parameter of type 'String'.
153+
```
154+
155+
#### **为什么不用`any`呢?**
39156

40157
使用 `any` 会丢失掉一些信息,我们无法确定返回值是什么类型
41158
泛型可以保证入参跟返回值是相同类型的,它是一种特殊的变量,只用于表示类型而不是值
42159

43-
语法 `<T>(arg:T):T` 其中`T`为自定义变量,能前后对应就行
160+
语法 `<T>(arg:T):T` 其中`T`为自定义变量
44161

45162
```js
46163
const hello : string = "Hello vue!"
@@ -77,4 +194,95 @@ console.log(say(1)) // Argument of type '1' is not assignable to parameter of t
77194
console.log(say({value: 'hello vue!', length: 10})) // { value: 'hello vue!', length: 10 }
78195
```
79196

197+
### 义叉类型
198+
199+
交叉类型(Intersection Types),将多个类型合并为一个类型
200+
201+
```js
202+
interface foo {
203+
x: number
204+
}
205+
interface bar {
206+
b: number
207+
}
208+
type intersection = foo & bar
209+
const result: intersection = {
210+
x: 10,
211+
b: 20
212+
}
213+
const result1: intersection = {
214+
x: 10
215+
} // error
216+
```
217+
218+
### 联合类型
80219

220+
交叉类型(Union Types),表示一个值可以是几种类型之一。 我们用竖线 | 分隔每个类型,所以 number | string | boolean表示一个值可以是 number, string,或 boolean
221+
222+
```js
223+
type arg = string | number | boolean
224+
const foo = (arg: arg):any =>{
225+
console.log(arg)
226+
}
227+
foo(1)
228+
foo('2')
229+
foo(true)
230+
```
231+
232+
### 函数重载
233+
234+
函数重载(Function Overloading), 允许创建数项名称相同但输入输出类型或个数不同的子程序,可以简单理解为一个函数可以执行多项任务的能力
235+
236+
例我们有一个`add`函数,它可以接收`string`类型的参数进行拼接,也可以接收`number`类型的参数进行相加
237+
238+
```js
239+
function add (arg1: string, arg2: string): string
240+
function add (arg1: number, arg2: number): number
241+
242+
// 实现
243+
function add <T,U>(arg1: T, arg2: U) {
244+
// 在实现上我们要注意严格判断两个参数的类型是否相等,而不能简单的写一个 arg1 + arg2
245+
if (typeof arg1 === 'string' && typeof arg2 === 'string') {
246+
return arg1 + arg2
247+
} else if (typeof arg1 === 'number' && typeof arg2 === 'number') {
248+
return arg1 + arg2
249+
}
250+
}
251+
252+
add(1, 2) // 3
253+
add('1','2') //'12'
254+
```
255+
256+
### 总结
257+
258+
通过本篇文章,相信大家对`Typescript`不会再感到陌生了
259+
260+
下面我们来看看在`Vue`源码`Typescript`是如何书写的,这里我们以`defineComponent`函数为例,大家可以通过这个实例,再结合文章的内容,去理解,加深`Typescript`的认识
261+
262+
```js
263+
// overload 1: direct setup function
264+
export function defineComponent<Props, RawBindings = object>(
265+
setup: (
266+
props: Readonly<Props>,
267+
ctx: SetupContext
268+
) => RawBindings | RenderFunction
269+
): {
270+
new (): ComponentPublicInstance<
271+
Props,
272+
RawBindings,
273+
{},
274+
{},
275+
{},
276+
// public props
277+
VNodeProps & Props
278+
>
279+
} & FunctionalComponent<Props>
280+
281+
// defineComponent一共有四个重载,这里省略三个
282+
283+
// implementation, close to no-op
284+
export function defineComponent(options: unknown) {
285+
return isFunction(options) ? { setup: options } : options
286+
}
287+
288+
```

docs/global/createApp.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const HelloVueApp = {
1515

1616
Vue.createApp(HelloVueApp).mount('#hello-vue')
1717
```
18-
<a href="/run/start" target="_blank">亲自试一试</a>
18+
<a href="/run/start.html" target="_blank">亲自试一试</a>
1919

2020
那么 `createApp` 里面都干了什么呢?我们接着往下看
2121

docs/global/h.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ const App = {
4545
}
4646
Vue.createApp(App).mount('#app')
4747
```
48-
<a href="/run/h" target="_blank">亲自试一试</a>
48+
<a href="/run/h.html" target="_blank">亲自试一试</a>
4949

5050
### 都干了些啥
5151

docs/global/nextTick.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ export function nextTick(fn?: () => void): Promise<void> {
6969
return fn ? p.then(fn) : p
7070
}
7171
```
72-
<a href="/run/nextTick-demo-1" target="_blank">亲自试一试</a>
72+
<a href="/run/nextTick-demo-1.html" target="_blank">亲自试一试</a>
7373

7474
看到这里,有的同学可能又会问,前面我们猜想的 `DOM` 更新也是异步任务,那他们的这个执行顺序如何保证呢?
7575

0 commit comments

Comments
 (0)