简单认识TS
TS是什么,为什么有学的必要
即,JS本身是一个动态、弱类型的语言,在搭建大型项目时,很容易因为变量类型导致一些不容易被发现的错误。
引入TS,使得项目更清晰,实现了类型安全,同时扩展了下一代JS的用法,提供了完善的工具链。
TS开源教程:awesome-typescript
TS在线编译(生成对应的JS文件):TypeScript: TS Playground
TS基础
基本变量:
- number、boolean、string
- any、unknown、void
- 枚举enum(ts特有,映射和反映射
- never(永远不存在值)
- 数组类型[]
- 元组类型tuple
关于 any、unknown、void
any:任意类型的变量
unknown:一个安全的但未知的变量,可以赋给unknown, any
void:用于表示函数不返回值
函数类型
function add(x: number[]): number
function add(x: string[]): string
function add(x: any[]): any {
if (typeof x[0] === 'string') {
return x.join();
}
if (typeof x[0] === 'number') {
return x.reduce((pre, cur) => pre + cur)
}
}
复制代码
需要定义形参的变量类型,函数的返回值类型
可以重载(名称相同,形参、返回值类型不同)
接口
定义对象类型
声明一个规范,使用接口的对象必须满足这些规范
设置规范的特点:
- 可选属性
a?: number - 只读属性
readonly a: number
interface Person {
name: string,
age: number
}
类
加入了与C++相似的 public protected private 修饰符
用于规定访问变量的权限
public 可以在任意位置访问
protected 可以在类、子类、同一个包中访问
private 仅在同类中访问
同时引入 C++ 抽象类
abstract class Animal { //定义一个抽象类
abstract name: string //一个抽象属性
age: number //这是一个普通属性
abstract eat(): void //一个抽象方法
run(): void { //这是一个普通方法 }
}
含有抽象属性或抽象方法的类是抽象类。
- 抽象属性:只定义变量名和变量类型,不允许赋值。
- 抽象方法:只定义函数名、参数及其类型、返回值的类型,不做实现。
抽象类不能实例化,继承抽象类的子类必须实例化抽象类中的所有抽象变量和抽象方法。
即,抽象类是一种类要实现的内容的规范。(描述了类要包含什么属性、为类要实现的方法指定接口)
继承抽象类的子类即,对应规范的具体实现。
与接口的对比:
- 继承抽象类
extends - 实现接口
implements
高级类型
联合类型 |、交叉类型&
联合类型:允许一个变量存储多种类型的值
let num: number | string
交叉类型:用于合并多个接口,通常用于规范对象
interface Person {
name: string,
age: number
}
interface Lesson {
classid: number
}
type Student = Person & Lesson
// 等效于
interface Student {
name: string,
age: number,
classid: number
}
交叉类型类似于接口的继承,但是,当接口有冲突时,使用继承会报错,但使用交叉类型会合并。
interface Ia {
foo(x: number): number
}
interface Ib {
foo(b: string): number
}
type Ic = Ia & Ib
// 等效于
interface Ic {
foo(x: number | string): number
}
类型断言
即先假定变量是某一类型,使得在访问其中属性时,编译器不报错。
在使用联合类型时,对于可能有多种类型的变量,在不确定具体类型时,直接使用其属性,会报错。因此,使用断言,先告诉解析器,此变量的类型。
属性前置的断言定义:
function getLength(x: string | number): number {
return x.length;
//此时,编译器不知道x是否是string,不能确定有length属性,因此报错
}
复制代码
使用类型断言 as 解决冲突:
function getLength(x: string | number): number {
const str = x as string; // 先用断言,假定x是string类型
if( str.length ) {
return x.length
}
else {
const num = str as number; //此时,确认x是number类型
return num.toString().length
}
}
类型别名
类似于C++的 typedef 将一种类型起别名
与 interface 的比较:
type 主要用于给基本类型(也包括函数)起别名,重复声明会被覆盖interface 用于类的规范,重复声明会合并
type 可以通过 & 与 type合并
interface 可以通过 extends 继承 interface
此外, type 可以通过 in 遍历,interface不行
组合和交叉类型的时候使用type 涉及类,定义对象和函数,使用interface
泛型
应用场景
打印string->打印numer->打印任何类型
使用类型占位符,输入具体类型时,再确定。
基本语法
常用的运算符: