TS的基础类型
- boolean、number、string
- undefined、null
- any、unknown、void
- never
- Array[]
- 元组类型tuple
TS函数类型
在TS中定义函数类型时需要定义输入参数类型和输出类型。其中,输入类型不像JS那样,在TS中,要求形参和实参的数量必须完全一样。
一个函数的定义包括函数名、参数、逻辑和返回值。例如:
function add(x: number, y: number): number { return x + y; }
let myAdd = function(x: number, y: number): number { return x + y; };
在TS中,我们可以对函数进行重载,重载允许一个函数接受不同数量或类型的参数时,作出不同的处理。
重载是方法名字相同,而参数不同,返回类型可以相同也可以不同。 例如:可以使用重载定义多个 reverse 的函数类型:
function reverse(x: number): number;
function reverse(x: string): string;
function reverse(x: number | string): number | string | void {
if (typeof x === 'number') {
return Number(x.toString().split('').reverse().join(''));
} else if (typeof x === 'string') {
return x.split('').reverse().join('');
}
}
interface
接口是为了定义对象类型 interface其实就是一种约束,他定义了一个形状,然后匹配实现其的对象是否一样。与class的区别在于:interface在编译后会消失 例如(一个错误的demo,证明是一种约束):
//这样写是会报错的 因为我们在person定义了a,b但是对象里面缺少b属性
//使用接口约束的时候不能多一个属性也不能少一个属性
//必须与接口保持一致
interface Person { b:string, a:string }
const person:Person = { a:"213" }
class
类的定义与js中一样,我们对于类的约束。也可以用接口来实现。
与JS不同在于,多了一些,变得更像Java了。多了public、protected、private修饰符、抽象类、继承等特点。这些特点和Java等传统语言一样。就不多讲述啦
TS高级类型
联合类型 |
联合类型可以当成一个并集,例如我们定义了一个变量,他可能为number类型,也可能为string类型,那么我们在为其声明定义的时候,可以用联合类型
let a: number | string = 1;
a = "hello";
交叉类型 &
交叉类型就有点类似于交集了,他要求变量必须属于交叉的多个类型(不是之一),举个例子可能更好理解:
//我们定义了两个interface
//让peson属于这两个类型
//与extends 类似,person具有两个对象的属性,不能多也不能少
interface People { age: number, height: number }
interface Man{ sex: string }
const person = (man: People & Man) => {
console.log(man.age)
console.log(man.height)
console.log(man.sex)
}
person({age: 18,height: 180,sex: 'male'});
类型断言 as
类型断言可以用来手动指定一个值的类型,即允许变量从一种类型更改为另一种类型。通过 变量 as 类型 的方法
通过类型断言这种方式可以告诉编译器,“相信我,我知道自己在干什么”。 类型断言好比其它语言里的类型转换,但是不进行特殊的数据检查和解构。 它没有运行时的影响,只是在编译阶段起作用,在编译过程中会被删除。 不被称为类型转换,是因为转换通常意味着某种运行时的支持。
需要注意的是,类型断言只能够「欺骗」TypeScript 编译器,无法避免运行时的错误,反而滥用类型断言可能会导致运行时错误
类型别名 type
type 关键字可以给一个类型定义一个名字,也就是重命名
例如我觉得string太长了,那么我们可以为string类型重命名为str
只需要type str = string就可。后续我们都可以用str来代替string。
其实可以看出,type与interface的功能好像类似。都可以给类型取别名 他们的相同点:
- 都可以定义对象或函数
- 都允许继承
差异点︰
- interface是TS用来定义对象,type是用来定义别名方便
- type可以定义基本类型,interface不行;
- interface可以合并重复声明,type不行;
TS泛型
TS的泛型与Java中的类似,都是通过<>里面来写一个类型参数。其作用是临时占位,之后通过传来的类型进行推导。也就是说,相同的泛型参数名(例如T) 的类型都是一样的。
尽管泛型非常好用,但是也不看滥用,因此我们需要对泛型进约束,通常是使用
- typeof:获取类型
- keyof:获取所有键(例如一个interface的属性)
- extends:包含
例如:
let obj = {
name:'zzk',
sex:'男'
}
// 第一个类型希望传入的是引用类型
// 第二个类型希望传入的是对象里面的属性名
// keyof T :返回联合类型,也就是返回T类型的所以键,在该demo中,T 为 obj,所以就是 keyof obj
// 得到了obj的键(name|sex) 而 extends代表 K 必须属于这个联合类型(name|sex)
function ob<T extends object,K extends keyof T>(obj:T,key:K){
return obj[key]
}
ob(obj,'name')
在该demo中,使用了TS泛型和泛型约束。
首先定义了T类型并使用extends关键字继承object类型的子类型,
然后使用keyof操作符获取T类型的所有键,它的返回类型是联合类型,
最后利用extends关键字约束 K类型必须为keyof T联合类型的子类型