TS基础笔记 | 青训营笔记

77 阅读4分钟

TS的基础类型

  1. boolean、number、string
  2. undefined、null
  3. any、unknown、void
  4. never
  5. Array[]
  6. 元组类型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的功能好像类似。都可以给类型取别名 他们的相同点:

  1. 都可以定义对象或函数
  2. 都允许继承

差异点︰

  1. interface是TS用来定义对象,type是用来定义别名方便
  2. type可以定义基本类型,interface不行;
  3. 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联合类型的子类型