TypeScript 基础
介绍
TypeScript 是 JavaScript 的一个超集,添加了静态类型和基于类的面向对象编程。
使用 .ts 作为文件扩展名。
安装
- 使用 npm(需要安装 Node.js)。在终端中运行以下命令:
1 | npm install -g typescript |
数据类型
布尔值(boolean)
布尔值用于存储true/false值。
1 | let isDone: boolean = false; |
数字(number)
TS里的所有数字都是浮点数。 这些浮点数的类型是 number。
并且支持二进制、八进制、十进制与十六进制字面量面量。
1 | let binary: number = 0b1010; // 二进制 |
字符串(string)
字符串用于处理网页或服务器端的文本数据。
1 | let greeting: string = "hello"; |
空值 Void、Null 和 Undefined
null 和 undefined 是两个不同的类型。
- void。表示没有任何类型,比如函数没有返回值时。
- null 表示一个空值,通常用于表示“无”或“未知”。
- undefined 表示一个变量未被赋值。
默认情况下 null 和 undefined 是所有类型的子类型。
Any
any 类型表示任何类型的值。使用 any 类型可以让你在编程时更加灵活,但也会失去类型检查的好处。
Never
never类型表示的是那些永不存在的值的类型。
never 类型是任何类型的子类型,也可以赋值给任何类型。
然而,没有类型是 never 的子类型或可以赋值给 never 类型,即便是any也不行。
数组(Array/[])
数组用于存储多个相同类型的集合。
可以使用类型[]或使用Array<类型>来表示数组。
1 | let numbers: number[] = [1, 2, 3]; |
元组(Tuple)
元组类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同。
当访问一个已知索引的元素,会得到正确的类型:
1 | let tuple: [string, number]; |
枚举(Enum)
枚举类型可以为一组数值赋予友好的名字。
默认情况下,从 0 开始为元素编号。
枚举类型可以由枚举的值得到它的名字。
1 | enum Color { |
也可以手动的指定成员的数值。
枚举类型支持指定数字、字符串枚举和异构枚举。
1 | enum Color { |
对象(Object)
object 表示非原始类型
函数(Function)
以像变量一样被传递和使用。
1 | function add(x: number, y: number): number { |
默认参数、可选参数与剩余参数
1 | // firstName = "John" 是默认参数 |
泛型
泛型用于创建可重用的组件
泛型函数
通过在函数名后面添加 <T,...> 来定义泛型函数,其中 T、... 是类型变量,可以在函数体内当作类型使用。
使用 extends 关键字来约束类型变量。
1 | function identity<T extends U, U>(arg: T): T { |
泛型类
1 | class GenericNumber<T> { |
接口(Interface)
接口用于定义对象的结构和类型。
支持可选属性、只读属性、函数类型、索引类型等。
1 | interface Person { |
使用 implements 关键字来实现重写接口
- 可以重写属性和方法
使用 extends 关键字来继承接口
- 不可以重写属性,但可以重写方法
- 可以继承多个接口
1 | interface Animal { |
交叉类型(Intersection Types)
交叉类型是将多个类型合并为一个类型。
可以把现有的多种类型叠加到一起成为一种类型,其包含了所需的所有类型的特性。
使用&符号来表示交叉类型。
Person & Serializable & Loggable同时是 Person 和 Serializable 和 Loggable。
就是说这个类型的对象同时拥有了这三种类型的成员。
联合类型(Union Types)
联合类型表示一个值可以是几种类型之一。
使用|符号来表示联合类型。
number | string | boolean表示一个值可以是 number, string,或 boolean。
类型操作
类型断言
类型断言是一种手段,可以用来告诉编译器变量的实际类型。
类型断言有两种形式:
- 尖括号语法:
(<类型>变量名) - as 语法:
(变量名 as 类型)
类型保护
当类型可能是几个类型之一时,需要每次使用类型断言使编译器知道其确切类型。
TS 提供了多种方式来来做到这一点。
- 使用
typeof进行类型保护
1 | // 使用 typeof 进行类型保护 |
- 使用
instanceof进行类型保护
1 | // 使用 `instanceof` 进行类型保护 |
- 使用自定义的类型保护函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21// 使用 类型保护函数,函数返回值类型为:`变量名 is 类型`
interface Dog {
bark:() => void;
}
interface Cat {
meow: () => void;
}
function example(animal: Dog | Cat) {
const isDog = (animal: Dog | Cat): animal is Dog => {
return (animal as Dog).bark !== undefined;
}
if (isDog(animal)) {
// 在这个分支中,animal 的类型被缩小为 Dog
animal.bark();
} else {
// 在这个分支中,animal 的类型被缩小为 Cat
animal.meow();
}
}
typeof只能用于基本类型的类型保护,instanceof只能用于构造函数的类型保护。
而自定义的类型保护函数可以用于任何类型的类型保护。
映射类型
TypeScript提供了从旧类型中创建新类型的一种方式。 在映射类型里,新类型以相同的形式去转换旧类型里每个属性。
一些常用的映射类型有:
Partial<T>– 将类型T的所有属性变为可选。Required<T>– 将类型T的所有属性变为必需。Readonly<T>– 将类型T的所有属性变为只读。Pick<T, K>– 从类型T中选择一组属性K来构造新类型。Exclude<T, U>– 从T中剔除可以赋值给U的类型。Extract<T, U>– 提取T中可以赋值给U的类型。NonNullable<T>– 从T中剔除null和undefined。ReturnType<T>– 获取函数返回值类型。InstanceType<T>– 获取构造函数类型的实例类型。