# TypeScript 常用类型
# 1. 概述
JS 已有类型:
- 原始类型: number / string / boolean / null / undefined / symbol
- 对象类型: object (包括 数组、对象、函数)
TS 新增类型:
- 联合类型
- 自定义类型(类型别名)
- 接口
- 元组
- 字面量类型
- 枚举
- void
- any
- ......
# 2. 类型注解
let age: number = 18
: number
就是类型注解,限制变量的类型,只能给变量赋值该类型的值。
# 3. 原始类型
完全按照 JS 中类型的名称来书写即可:
let age : number = 18
let personName : string = '张三'
let isLoading : boolean = false
let obj : null = null
let myVar : undefined = undefined
let id : symbol = Symbol()
# 4. 数组类型
说明:
- 在 JS 中,只有 object 类型; 在 TS 中,把 object 细化了。
示例:(推荐使用第一种写法)
let num1: number[] = [1, 2, 3]
let num2: Array<number> = [1, 2, 3]
# 5. 联合类型
说明:
- 由多个类型组成的类型,表示可以是这些类型中的任意一种
- 由
|
连接多个类型
示例:
let age: number | string;
age = 1;
age = 'a';
let names: (number | string)[];
names = [1, 'a'];
# 5.1. 类型别名
说明:
- 某个类型多次使用,可以抽取成类型别名,达到复用的目的
- 使用
type
关键字
示例:
// 定义类型别名
type CustomArray = (number | string)[];
// 使用
let arr: CustomArray = [1, 'a']
# 6. 函数类型
函数的类型实际上是: 函数参数和返回值的类型
有两种指定方式:
- 单独指定 参数和返回值 的类型
- 同时指定 参数和返回值 的类型
# 6.1. 单独指定
说明:
- 在 形参 后面添加 参数的类型注解
- 在 函数小括号 后面添加 返回值的类型注解
示例:
function add(num1: number, num2: number): number {
return num1 + num2;
}
const sum = function (num1: number, num2: number): number {
return num1 + num2;
}
const sum2 = (num1: number, num2: number): number => {
return num1 + num2;
}
# 6.2. 同时指定
说明:
- 只适用于 函数表达式
示例:
// 声明时,(以箭头函数形式)指定类型
let sum: (num1: number, num2: number) => number;
// 赋值
sum = (num1, num2) => {
return num1 + num2;
}
// 声明和赋值也可以写在一起,但不容易区分
# 6.3. 可选参数
说明:
- 传参时,可传可不传
- 不能位于必选参数之前
示例:
function test(arg1: number, arg2?: number, arg3?: number): void {
console.log(arg1, arg2, arg3)
}
test(1) // 1 undefined undefined
test(1, 2) // 1 2 undefined
test(1, 2, 3) // 1 2 3
# 6.4. void 类型
说明:
- 如果函数没有返回值,则返回值类型为 void
示例:
function greet(name: string): void {
console.log(`${name}, hello!`);
}
# 7. 对象类型
说明:
- 描述对象的结构
- 单行时,用
;
分隔;多行时,可以省略分号
示例:
let person: {
// 属性
name: string;
// 方法
sayHi(name: string): void
sayHello: (name: string) => void // 箭头函数形式
} = {
name: '张三',
sayHi(name) {
console.log(name, 'hi');
},
sayHello(name) {
console.log(name, 'hello');
}
}
# 7.1. 可选属性
说明:
- 语法与函数可选参数一致,都使用
?
来表示
示例:
let student: {
name: string;
age?: number;
};
student = { name: '张三' };
student = { name: '张三', age: 18 };
# 8. 接口
说明:
- 对象类型多次使用,可以抽取成接口(interface),达到复用的目的
- 使用
interface
关键字定义
示例:
interface IPerson {
name: string;
sayHi(): void;
}
let person: IPerson = {
name: '张三',
sayHi() {
console.log(this.name, 'hi');
}
}
# 8.1. interface vs type
说明:
- 接口 只能给对象指定类型
- 类型别名 可以为任意类型指定别名
示例:
type IPerson = {
name: string;
sayHi(): void;
}
let student: IPerson = {
name: '张三',
sayHi() {
console.log(this.name, 'hi');
}
}
type StrNum = string | number;
# 8.2. 继承
说明:
- 将公共的属性、方法抽离出来,通过继承来实现复用
- 通过 extends 关键字,子接口拥有父接口所有属性和方法
示例:
interface Point2D {
x: number;
y: number;
}
interface Point3D extends Point2D {
z: number;
}
const p: Point3D = { x: 1, y: 2, z: 3 };
# 9. 元组(tuple)
说明:
- 特殊的数组
- 指定元素的个数 以及 每个元素的类型
示例:
let position: [number, number] = [39, 116];
# 10. 类型推论
说明:
- 在某些没有明确指出类型的地方,TS的类型推论机制会帮助提供类型
- 常见场景:1. 声明变量并立即初始化时; 2. 函数返回值
示例:
/*
等价:
let age: number = 12;
*/
let age = 12;
/*
等价:
function sum(num1: number, num2: number): number {
return num1 + num2
}
*/
function sum(num1: number, num2: number) {
return num1 + num2
}
# 11. 类型断言
说明:
- 设置更具体的类型(强转为某个类型)
- 查看 DOM 元素具体的类型:
element.__proto__
示例:
// 类型推论是 HTMLElement
let aLink1 = document.getElementById('aLink');
// 断言为(强转为)HTMLAnchorElement
let aLink2 = document.getElementById('aLink') as HTMLAnchorElement;
// 也可以使用 `<>` 语法,但是与 JSX 冲突
let aLink3 = <HTMLAnchorElement> document.getElementById('aLink');
# 12. 字面量类型
说明:
- JS 中的字面量可以作为类型来使用
- 字面量类型 通常与 配合联合类型 一起使用,用来表示一组明确的可选值
示例:
// 字面量类型单独使用基本没啥意义
let age: 18 = 18;
let stuName: '张三' = '张三'
// 字面量类型与联合类型一起使用,表示一组明确的可选值
let direction: 'up' | 'down' | 'left' | 'right' = 'up';
function setDirection(direction: 'up' | 'down' | 'left' | 'right') {
// ...
}
setDirection('up');
# 13. 枚举
说明:
- 定义这一组命名常量。类型为该枚举的变量,其值可以是这些常量中的一个。
- 类似于 字面量类型+联合类型,也可以表示一组明确的可选值
- 通过
enum
关键字定义
示例:
// 定义枚举
enum Direction {
Up,
Down,
Left,
Right
}
// 使用枚举类型
function setDirection(direction: Direction) {}
// 访问枚举成员
setDirection(Direction.Up);
# 13.1. 数字枚举
说明:
- 枚举成员是有值的,默认是从 0 开始自增的数值
- 枚举成员的值是数字的枚举,称为 数字枚举
示例:
// 默认从 0 开始,后面成员的值 = 前面成员的值 + 1
enum Direction1 {
Up, // 0
Down, // 1
Left, // 2
Right, // 3
}
// 指定第一个成员为 10
enum Direction2 {
Up = 10, // 10
Down, // 11
Left, // 12
Right, // 13
}
// 挨个指定成员的初始值
enum Direction3 {
Up = 10, // 10
Down = 11 , // 11
Left = 22 , // 22
Right, // 23
}
# 13.2. 字符串枚举
说明:
- 枚举成员的值是字符串,称为 字符串枚举
- 字符串枚举没有自增长行为,所有成员必须指定初始值
示例:
enum Direction {
Up = 'UP',
Down = 'DOWN',
Left = 'LEFT',
Right = 'RIGHT',
}
# 13.3. 原理
说明:
- 一般类型编译为 JS 代码后会被移除
- 枚举不仅用作类型,还提供值,编译后会额外生成一段 JS 代码
- 推荐使用 字面量类型+联合类型 的方式,更直观、简洁、高效
示例:
/*
编译为 JS:
var Direction1;
(function (Direction1) {
Direction1["Up"] = "UP";
Direction1["Down"] = "DOWN";
Direction1["Left"] = "LEFT";
Direction1["Right"] = "RIGHT";
})(Direction1 || (Direction1 = {}));
*/
enum Direction1 {
Up = 'UP',
Down = 'DOWN',
Left = 'LEFT',
Right = 'RIGHT',
}
/*
编译为 JS:
var direction = 'UP';
*/
type Direction2 = 'UP' | 'DOWN' | 'LEFT' | 'RIGHT';
let direction: Direction2 = 'UP';
# 14. any 类型
说明:
- 当值的类型为 any 时,可以对值进行任意操作,且不会有代码提示。(所以不要使用 any 类型)
- 隐式 any 类型:1. 声明变量时 不给初始值、类型注解;2. 函数参数不给类型注解
示例:
// 显式设置 any 类型,以下操作都没有提示
let a: any = {};
a.x;
a.y = 10;
a();
const n: number = a;
// 隐式 any 类型,声明变量 不给初始值、类型注解
let b;
b.x;
b.y = 10;
b();
// 隐式 any 类型,函数参数 不给类型注解
function add(num1, num2) {}
add(1, '2');
# 15. typeof
说明:
- TS 中,
typeof
在类型注解中使用,表示引用 变量或属性 的类型 - 可以用于引用默认参数的类型
示例:
console.log( typeof 'hello' ); // "string"
let person: { name: string, age: number } = { name: '张三', age: 18 };
/* 等价于:
let p2: { name: string, age: number } = { name: '李四', age: 19 };
*/
let p2: typeof person = { name: '李四', age: 19 };
/* 等价于:
let p2Name: string = '李四';
*/
let p2Name: typeof person.name = '李四';
上一篇: 下一篇:
本章目录