前情提要
# 教程1:花费一分钟,跟着做,傻瓜式入门Typescript
类型注解
格式为:类型
举例
let 变量: 变量类型
let uname: string; // 声明uname变量为string类型
let mySum: (x: number, y: number) => number // 对等号右侧的匿名函数进行了类型定义
function fn (形参: 形参类型): 返回值类型 { ... }
function callName (uname: string): string {
return '我的名字是' + uname
}
变量类型
number
let num: number = 10
string
let uname: string = 'lemon'
boolean
let isDone: boolean = false
字面量
let name: 'lemon' // name的值只能是'lemon'
let gender: 'male' | 'female' // gender的值只能是'male'或者'female
扩展:联合类型
// 联合类型: 表示一个值可以是几种类型之一,我们用竖线( |)分隔每个类型
// 如下:number | 'auto',表示一个值可以是 number, string,或 boolean。
let width: number | 'auto' // width的类型只能是number或者'auto'。
数组
let 变量: 类型[]let 变量: Array<类型>
// 例如:
let numArr: number[]
let strArr: Array<string>
元组 Tuple
可以理解为长度固定的数组,每一项的元素类型均已声明且可不同
// 例如:
let x: [string, number]
当添加越界的元素时,它的类型会被限制为元组中每个类型的联合类型:
let tom: [string, number];
tom = ['Tom', 25];
tom.push(true);
// Argument of type 'true' is not assignable to parameter of type 'string | number'.
object
// 任意数组、函数都是对象,所以以下写法意义不大
let obj: object
// 扩展:可以改写成以下写法
let obj: {
name: string, // obj的值对应的对象必须要有name属性
age?: number, // ?修饰符代表可选,obj的值对应的对象可以有age属性,也可以没有
[propName: string]?: any // ES6对象扩展的语法: [propName]代表任意属性名
}
枚举
使用枚举类型可以为一组数值赋予友好的名字
// 枚举时,默认从0开始为元素编号。
enum Color {
Red, // Color.Red = 0
Green, // Color.Green = 1
Blue // Color.Blue = 2
}
let c = Color.Green // 此时c的值为1
应用
// 假设res为后端返回颜色的数据
switch(res) {
case Color.Red:
***;
break;
case Color.Green:
***;
break;
case Color.Blue:
***;
break;
default:
***;
}
// 或者在vue项目中
new Vue({
data: {
color: Color,
res: 0 // res的值可变
}
})
<span :style="{ color: color[res].toLowerCase() }">我没想好这里写啥</span>
any
表示任意类型。当你希望跳过类型检查时使用,不推荐使用。
let a: any
let b // 声明变量时不指定类型,则默认为any类型
void
void类型像是与any类型相反,它表示没有任何类型。 当一个函数没有返回值时,你通常会见到其返回值类型是 void:
function warnUser(): void {
console.log("This is my warning message");
}
声明一个void类型的变量没有什么大用,因为你只能为它赋予undefined和null:
let unusable: void = undefined;
null 和 undefined
TypeScript里,undefined和null两者各自有自己的类型分别叫做undefined和null。 和 void相似,它们的本身的类型用处不是很大:
let u: undefined = undefined;
let n: null = null;
默认情况下null和undefined是所有类型的子类型。 就是说你可以把 null和undefined赋值给number类型的变量。
扩展(先了解)
前提:当你指定了--strictNullChecks标记(tsconfig.json配置后面会讲)
则null和undefined只能赋值给void和它们各自。
也许在某处你想传入一个 string或null或undefined,你可以使用联合类型string | null | undefined。
let s = "foo";
s = null; // 错误, 'null'不能赋值给'string'
let sn: string | null = "bar";
sn = null; // 可以
sn = undefined; // error, 'undefined'不能赋值给'string | null'
TypeScript会把 null和 undefined区别对待。
string | null, string | undefined和 string | undefined | null是不同的类型。
never
never类型表示的是那些永不存在的值的类型。
// 抛出异常的函数返回值类型
function error(message: string): never {
throw new Error(message);
}
// 根本就没有返回的函数的返回值类型
function infiniteLoop(): never {
while (true) {
}
}
类型推断
当没有对变量进行类型注解时,且声明变量时同时对变量赋值了,则ts编译器会根据值自动推断变量类型
let uname = 'lemon'
// ts类型推断为 let uname: string
let mySum = function (x: number, y: number): number {
return x + y;
}
/* ts类型推断为
let mySum: (x: number, y: number) => number
完整写法如下:
let mySum: (x: number, y: number) => number = function (x: number, y: number): number {
return x + y;
}
*/
类型断言
告诉解析器变量的类型。
类型断言不是类型转换,它只会影响 TypeScript 编译时的类型, 不会真的影响到变量的类型。
语法:
变量 as 类型
let str: any = "this is a string";
let strLength: number = (str as string).length;
<类型>变量
let str: any = "this is a string"
let strLength: number = (<string>str).length
应用
function introduce (obj: { name: string, gender: 'male' | 'female' }) {
console.log(obj.name, obj.gender)
}
// 报错写法:
let lemonObj = {
name: 'lemon',
gender: 'female' // 此时ts推断gender变量类型为string类型
}
handleRequest(lemonObj) // 所以传参会报错: Type 'string' is not assignable to type '"female" | "male"'.
// 正确写法1:
let lemonObj = {
name: 'lemon',
gender: 'female' as 'female' // 断言gender变量类型为'female’
}
// 正确写法2:
let lemonObj = {
name: 'lemon',
gender: 'female'
} as const // as const断言将宽泛的数据类型限定为具体的值类型
辛勤的前端园丁,立志于把每个知识点嚼碎了喂你嘴里!