前言
随着前端在各种类型的项目中扮演的角色越来越重要,人们发现 JavaScript
这门弱类型语言已经不能满足当下的需求,尤其是在一些大中型项目中,JavaScript
远远没有一些强类型语言用得顺手,而 TypeScript
因此诞生。
TypeScript 是什么?
简单来讲,TypeScript
是 JavaScript
的超集,它可以编译成纯 JavaScript
。
基础语法
基础类型
由于 TypeScript
是在 JavaScript
的基础上定义的,所以基础类型其实也是大同小异,这里仅列出来和 JavaScript
做一个对比。
- 布尔值
声明方式:let a: boolean = true
对比:JavaScript
中也存在布尔值类型。 - 数字
声明方式:let a: number = 2
对比:JavaScript
中也存在数字类型。 - 字符串
声明方式:let a: string = '233'
对比:JavaScript
中也存在字符串类型。 - 数组
声明方式:let a: number[] = [1,2,3]
对比:JavaScript
中也存在数组类型。 - 元组 Tuple
声明方式:let a: [number, string]
对比:JavaScript
中不存在这种类型。
说明:定义一个元组,相当于定义一个规定类型的数组;比如上面的变量a
,前两个元素只能对应number
类型和string
类型,而之后的元素的类型也只能是number
和string
中的一种。 - 枚举
声明方式:enum animal = {cat, dog, duck}
,let a: animal = animal.cat
,跟其他语言一样,如果不赋值的话,枚举值从0
到n
,当然也可以选择手动赋值。
对比:JavaScript
中不存在这种类型,不过枚举也可以简单的用声明常量的方式来代替。 - Any
声明方式:let a: any = '2333'
对比:JavaScript
中不存在这种类型。
说明:声明一个any
类型的变量,通常它表示所有类型的变量。 - Void
声明方式:let gg: void = undefined
对比:JavaScript
中存在void
,但它不是变量类型,而是一个操作符 - Null
声明方式:let a: null = null
对比:JavaScript
中存在Null
类型。
说明:Null
类型可以看成其他类型的子类型,也就是说Null
类型的变量也可以赋值给其他类型的变量并且不会报错。 - Undefined
声明方式:let a: undefined = undefined
对比:JavaScript
中存在Undefined
类型。
说明:Undefined
类型同上面所说的Null
一样,也是其他类型的子类型。 - Never
声明方式:无法声明,因为其他类型的变量不能给never
类型的变量赋值。never
类型只能从函数返回值中获取。
对比:JavaScript
中不存在never
类型。
说明:never
类型表示的是那些永不存在的值的类型。 - Object
声明方式:let a: object = {}
对比:JavaScript
中存在object
类型
接口
TypeScript
的核心原则之一是对值所具有的结构进行类型检查。 它有时被称做“鸭式辨型法”或“结构性子类型化”。 在TypeScript
里,接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约。
简单来说,接口(interface)存在的意义是为了对复杂类型(object)的存在进行约束。
比方说有一个对象 person,它有以下这些属性:
- 姓名
- 身高
- 体重
- ...
由于 person 是一个复杂的对象,使用接口(interface)则可以对它进行一个严格的约束。比如:
interface Person { name: string, height: number, weight: number }
可选属性
接口里的属性不全都是必需的。 有些是只在某些条件下存在,或者根本不存在。 可选属性在应用“option bags”模式时很常用,即给函数传入的参数对象中只有部分属性赋值了。
可选属性 的存在其实跟你有没有男/女朋友的关系是一样的,有固然好,没有也不会怎么样。不过你要是男女通吃那我也拿你没办法...
以此为例子,我们拓展下上面的代码:
interface Person {
name: string,
height: number,
weight: number,
girlFriend?: object,
boyFriend?: object
}
只读属性
如果有些属性只想赋值一次,那么只读属性就可以派上用场。
比方说我们的身高,在一定年龄后就不会再长,那么其实也可以把它近似的看成一个只读属性。
因此我们上面的代码也可以这样写。
interface Person {
name: string,
readonly height: number,
weight: number,
girlFriend?: object,
boyFriend?: object
}
函数
和JavaScript
一样,TypeScript
函数可以创建有名字的函数和匿名函数。 你可以随意选择适合应用程序的方式,不论是定义一系列API
函数还是只使用一次的函数。
TypeScript
中的函数跟 JavaScript
在书写方式上区别并不算很大,比如说定义一个 add
函数:
使用 JavaScript
是这样写的:
function add(a, b) {
return a + b
}
使用 TypeScript
是这样写的:
function add(a: number, b: number): number {
return a + b
}
那么 TypeScript
的函数就没点其他的功能了吗?其实还是有的。
可选参数和默认参数
- 可选参数:函数的参数可选
- 默认参数:函数的参数设置默认值
可选参数的写法:
function foo(a: number, b: string, c?: boolean): void {
console.log(a,b,c)
}
foo(1,'233') // 1, '233', undefined
设置了一个可选参数,如果不传值,那么它默认就是 undefined
默认参数的写法:
function foo(a: number, b: string, c = false): void {
console.log(a, b, c)
}
foo(1,'gg') // 1, 'gg', false
这里的默认参数跟 JavaScript
中的写法是等价的。
重载
函数重载意味着允许存在相同函数名,但是参数类型、个数、返回值其中的一个或多个不相同的函数。
当然,我们来看个简单的例子会更加清晰明了。比如说你的老大让你写一个 swap
函数,相信在座的各位前端er都能写出:
function swap(arr, i, j) {
let tmp = arr[i]
arr[i] = arr[j]
arr[j] = tmp
// [arr[i], arr[j]] = [arr[j], arr[i]] 利用解构也可以这样写
}
如果用 TypeScript
那就要指定参数 arr
的类型了,如果指定了 number[]
或者 string[]
之类的,那么未免太死板了;但是如果指定了 any
类型,那又没办法约束参数。而函数重载在这个时候就发挥了它的作用:
function swap(arr: number[], i: number, j: number)
function swap(arr: string[], i: number, j: number)
function swap(arr, i, j) {
[arr[i], arr[j]] = [arr[j], arr[i]]
}
练习地址:https://www.tslang.cn/play/index.html
参考资料:
扫描下方的二维码或搜索「tony老师的前端补习班」关注我的微信公众号,那么就可以第一时间收到我的最新文章。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。