Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 00cf9a5

Browse files
authored
Update typeScript.md
1 parent 86a4748 commit 00cf9a5

File tree

1 file changed

+237
-17
lines changed

1 file changed

+237
-17
lines changed

‎docs/es6/typeScript.md‎

Lines changed: 237 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,173 @@
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`
53+
54+
使用枚举类型可以为一组数值赋予友好的名字
1055
```js
11-
function sum(a: number, b: number): number {
12-
return a + b
56+
enum LogLevel {
57+
info = 'info',
58+
warn = 'warn',
59+
error = 'error',
1360
}
1461
```
15-
### 复合元素类型
62+
63+
- 元组 `Tuple`
64+
65+
允许数组各元素的类型不必相同。 比如,你可以定义一对值分别为 string和number类型的元组
66+
67+
```js
68+
// Declare a tuple type
69+
let x: [string, number];
70+
// Initialize it
71+
x = ['hello', 10]; // OK
72+
// Initialize it incorrectly
73+
x = [10, 'hello']; // Error
74+
```
75+
76+
- 任意值 `Any`
77+
78+
表示任意类型,通常用于不确定内容的类型,比如来自用户输入或第三方代码库
79+
1680
```js
17-
let arr:Array<number> = [1, 2, 3]
18-
let set:Set<number>=newSet([1, 2, 2])
19-
let map:Map<string, number>=newMap([['key1', 1], ['key2', 2]])
81+
let notSure: any = 4;
82+
notSure ="maybe a string instead";
83+
notSure =false; // okay, definitely a boolean
2084
```
21-
### 接口类型
85+
- 空值 `Void`
86+
87+
与 any 相反,通常用于函数,表示没有返回值
88+
89+
```js
90+
function warnUser(): void {
91+
console.log("This is my warning message");
92+
}
93+
```
94+
95+
- 接口 `interface`
96+
97+
类型契约,跟我们平常调服务端接口要先定义字段一个理
98+
99+
如下例子 point 跟 Point 类型必须一致,多一个少一个也是不被允许的
22100
```js
23101
interface Point {
24102
x: number
25103
y: number
104+
z?: number
105+
readonly l: number
26106
}
27-
const point: Point = { x: 10, y: 20 }
107+
const point: Point = { x: 10, y: 20, z: 30, l: 40 }
108+
const point2: Point = { x: '10', y: 20, z: 30, l: 40 } // Error
109+
const point3: Point = { x: 10, y: 20, z: 30 } // Error
110+
const point4: Point = { x: 10, y: 20, z: 30, l: 40, m: 50 } // Error
111+
28112
```
29-
### 类型别名
113+
114+
可选与只读 ? 表示可选参, readonly 表示只读
115+
116+
```js
117+
const point5: Point = { x: 10, y: 20, l: 40 } // 正常
118+
point5.l = 50 // error
119+
```
120+
121+
### 函数参数类型与返回值类型
122+
123+
```js
124+
function sum(a: number, b: number): number {
125+
return a + b
126+
}
127+
```
128+
129+
配合 `interface` 使用
130+
30131
```js
31-
type mathfunc = (a: number, b: number) => number
32-
const product: mathfunc = (a, b) => a * b
132+
interface Point {
133+
x: number
134+
y: number
135+
}
136+
137+
function sum({ x, y}: Point): number {
138+
return x + y
139+
}
140+
141+
sum({x:1, y:2}) // 3
33142
```
34143

35144
### 泛型
36-
泛型的意义在于函数的重用性,我们希望组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型
145+
泛型的意义在于函数的重用性,设计原则希望组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型
37146

38-
**为什么不用`any`呢?**
147+
* 比如
148+
149+
根据业务最初的设计函数 `identity` 入参为`String`
150+
```js
151+
function identity(arg: String){
152+
return arg
153+
}
154+
console.log(identity('100'))
155+
```
156+
157+
业务迭代过程参数需要支持 `Number`
158+
```js
159+
function identity(arg: String){
160+
return arg
161+
}
162+
console.log(identity(100)) // Argument of type '100' is not assignable to parameter of type 'String'.
163+
```
164+
165+
#### **为什么不用`any`呢?**
39166

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

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

45172
```js
46173
const hello : string = "Hello vue!"
@@ -77,4 +204,97 @@ console.log(say(1)) // Argument of type '1' is not assignable to parameter of t
77204
console.log(say({value: 'hello vue!', length: 10})) // { value: 'hello vue!', length: 10 }
78205
```
79206

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

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /