在 TypeScript 中,可以通过类型注释对变量、参数、返回值的类型进行标注。
- 声明变量如果不指定类型,则 TS 解析器会自动判断变量的类型为
any
(隐士 any),any 类型变量可以赋值给任意变量。
类型 | 说明 | 例子 |
---|---|---|
number | 任意数字 | 1, -33, 2.5 |
string | 任意字符串 | “h1”, “你好”, “1” |
boolean | 布尔值 | true, false |
object | 任意的 js 对象 | { “name”: “张三” } |
array | 任意 js 数组 | [1, 2, 3] |
null | 空 | * |
undefined | 未定义 | * |
字面量 | 限制变量的值就是该字面量的值 | 其本身 |
any | 任意类型 | * |
unknown | 类型安全的 any | * |
void | 没有值 (或 undefined) | 空值 (undefined) |
never | 不能是任何值 | 没有值 |
tuple | 元素,TS 新增类型,固定长度数组 | [4, 5] |
enum | 枚举,TS 新增类型 | enum{ A, B } |
类型声明
如果变量的声明和赋值同时进行,可以省略掉类型声明,TS可以自动对变量进行类型检测。
声明变量如果不指定类型,TS解析器会自动判断变量的类型为 any,相当于对该变量关闭了 TS 的类型检测。
// 定义变量 let 变量名: 类型; let 变量名 = 值; let 变量名: { 属性名: 类型, 属性名?: 类型 }; // 属性名后面加上?,表示可选类型 // 定义方法 function fn(参数名: 类型, 参数名: 类型): 返回值类型 { ... }; let 变量名 = (参数名: 类型, 参数名: 类型) => 返回值类型;
复制
// 数值类型 let apples: number = 5; // 字符串类型 let speed: string = "fast"; // 布尔值类型 let hasName: bolean = true; // 类型错误提示 apples = "5"; // 类型 'string' 不能功能类给类型 'number';
复制
# 联合类型 > 联合类型:可以赋值为指定的多个类型。 > 当没有确定类型时,会把两种类型共有的方法列出来
let c: boolean | string; c = true; c = 'hello';
复制
any 类型
变量中可以存储任何数据类型的值。
let anything: any = "Hello TypeScript"; anything = 10; anything = false; anything = function () {};
复制
- 隐士 any:只定义了变量名,没有定义类型,也没有赋值。
复制let c;
Array 数组
在没有为数组显示标注类型时,变量的初始值又是一个空数组,此时该数组中可以存储任何类型的值。虽然写法正确,但丢失了 TypeScript 类型检查功能。
-
可以设置任意类型的值。
复制let colors = any[]; let colors = []; colors = [1, 2, 3, 4, 5]; colors = ["1", "2", "3", "4"]; colors = [false, true]; -
只能设置单个类型的数组。
复制# 语法格式 let 变量名: 类型[] = [值1, 值2, 值3]; let 变量名: Array<类型> = [值1, 值2]; // 也可以声明,比较麻烦 let colors: string[] = ["1", "2", "3", "4"]; // 只能设置数字数组 let colors: number[] = [1, 2, 3, 4, 5]; -
二维数组。
复制# 语法格式 let 变量名: 类型[][] = [ [值1, 值2], [值1, 值2] ]; let carMarkers: string[][] = [ ["奔驰", "奥迪"], ["宝马"] ];
Tuples 元组
元组是 TypeScript 引入的一种新数据类型,它像数组一样工作,但是有一些额外的限制:元素中个数是固定,元组找那个元素类型已知。
元组用来存储一些以特定顺序出现且相关关联的数据,通过元组可以约束元素的个数及元素类型。
// 元组数组存储RGB颜色 var rgb = [number, number, number, number] = [255, 0, 0, 0.2]; // 元组数组(二维数组) var employee[number, string][] = [ [1, "Tom"], [2, "Cat"] ];
复制
Enum 枚举
用于存储一组密切相关且有限的值,可以提升代码的可读性,可以限定值的范围。例:消息的阅读状态、比赛结果、考试成绩、颜色种类、性别。
约定:枚举变量首字母大写。
// 如果枚举没有设置值时,默认值从0开始 enum Sizes { Small, Medium, Large }; console.log(Sizes.Small); // 默认是:0 1 2
复制
// 如果枚举设置默认值,则从设置的值开始往后依次+1,前面的值还是从0开始+1 enum Sizes { Small, // 0 Medium = 2, // 2 Large // 3 }; console.log(Sizes.Large); // 3
复制
注意:如果枚举为非数值,则每个属性都必须进行初始化。
enum Sizes { Small = "Small", Medium = "Medium", Large = "Large" }; console.log(Sizes.Small); // Small
复制
枚举编译后变为 js 对象。
enum Sizes { Small = "Small", Medium = "Medium", Large = "Large" };
复制
- 编译后的 js 对象。
复制var Sizes; (function (Sizes) { Sizes["Small"] = "s"; Sizes["Medium"] = "m"; Sizes["Large"] = "l"; })(Sizes || (Sizes = {}));
在声明枚举类型时,如果使用 const
关键字,TypeScript 编译器将输出更加简洁的代码。即:枚举本身不会被编译到 js 文件中。
const enum Sizes { Small = "s", Medium = "m", Large = "l" }; let selected = Sizes.Large; console.log(selected); // 编译结果 var selected = "l" /* Large */; console.log(selected);
复制
类型使用枚举
// 枚举 emun Gender { Male = 0, Female = 1 }; let i: { name: String, gender: Gender }; i = { name: '张三', gender: Gender.Male };
复制
Function 函数
通过类型注释可以显示设置函数将要接收的参数的类型,函数将要返回的值的类型。
// 普通写法 // function 方法名(参数1: 类型, 参数2: 类型): 返回值类型 {} function add(a: number, b: number): number { return a + b; }; // 箭头函数写法 // const 变量名 = (参数1: 类型, 参数2: 类型) => 返回值类型 const add = (a: number, b: number): number => { return a + b; }; // 调用参数要和类型一样 add(10, 20);
复制
// 没有返回值使用 void 进行标注 function log(): void {};
复制
可选参数
可选参数格式:
参数名?:类型
。
function sum(a: number, b: number, c?: number): number { // 可选参数c有值 if(typeof c !== "undefined") { return a + b + c; }; // 可选参数c没值 return a + b; }; sum(10, 20, 30); // 60
复制
// 默认值方式设置可选参数 function sum(a: number, b: number, c: number = 0): number { return a + b + c; }; sum(10, 20); // 30
复制
解构语法设置类型
// 解构出来的值设置类型 function logWeather({ data, weatcher }: { date: Date; weatcher: string }) { console.log(date, weatcher); }; // 要传递的参数 const weatcher = { date: new Date(), weatcher: "sunny" }; // 调用 logWeather(weatcher);
复制
Object 对象
// 对象字面量:以{}的形式创建对象,而不是new Object()创建 let point: { x: number, y: number } = { x: 100, y: 200 };
复制
// readonly 关键字把数据变为只读 let employee: { readonly id: number } = { id: 1 };
复制
// 可选参数 let student = { age?: number } = {}; student.age = 20;
复制
// 内置对象,类本身可以作为类实体的类型 let 变量名: 类名 = new 类(); let date: Date = new Date(); // 自定义类 class Car = {}; let car: Car = new Car();
复制
只读属性
使用
readonly
修饰的属性是只读属性,不可以修改。
let person = { readonly name: string, age: number } = { name: "张三", age: 18 }; // 只能修改age person.age = 20;
复制
类型推断
TypeScript 编译器能根据一些简单的规则推断变量的类型,在没有显示设置变量类型的情况下,编译器将变量初始值的类型作为该变量的类型。
- 不推荐使用,这样就失去了类型约束的意义。
let apples = 5; // 类型为 number let speed = "fast"; // 类型为 string let anything = []; // 类型为 any[]
复制
TypeScript 会试图推断函数返回值的类型。
使用函数返回值类型判断时,在编写函数内部代码时就会失去类型检测功能,所以函数返回值类型推荐明确指定。
如果函数的返回值是undefined
,可以指定函数的返回值为void
。
-
推断返回值类型为
number
。
复制// const add = (a: number, b: number) => number const add = (a: number, b: number) => { return a + b; }; -
推断返回值类型为
void
。
复制// const add: (a: number, b: number) => void const add = (a: number, b: number) => {}; -
推断返回值类型为
string | boolean
。
复制// const find = (name: string) => string | boolean; const find = (name: string) => { if (name) { return name; } else { return false; }; };
在 TypeScript 编译器可以推断出变量类型的情况下,开发者不需要显式编写类型注释,也就是说只有在 TypeScript 不能正确推断变量类型的情况下开发者才需要编写类型注释。
-
如果变量声明后没有被立即初始化,TypeScript 编译器不能正确推断出它的类型。
复制// TypeScript 编译器认为是 any 类型,失去了 TypeScript 中的类型检查功能 let anything; // let anything: any; anything = 10; anything = "hello"; -
调用的函数返回值是 any 类型时,应该使用显式声明它的类型。
复制let json = '{"name": "张三"}'; // let person: any => let person: {name: string} let person = JSON.parse(json);