likes
comments
collection
share

快速上手 TS(进阶类型篇)今天我们来学习一下 TS 的进阶知识,数组、元组、函数、接口等等,具体可以参考目录,还是那句

作者站长头像
站长
· 阅读数 20

快速上手 TS(进阶类型篇)今天我们来学习一下 TS 的进阶知识,数组、元组、函数、接口等等,具体可以参考目录,还是那句

前言

前两篇中我介绍了 TS 从安装到运行的环境配置,以及 TS 的基础类型介绍,希望能够对你带来帮助。今天我们来学习一下 TS 的进阶知识,数组、元组、函数、接口等等,具体可以参考目录,还是那句话希望我能坚持更新,更希望你能坚持看下去!

数组

在 JS 中数组就是数组,但 TS 中的数组被分为了数组和元组

数组

TS 数组有一个根本的特征,所有的成员类型必须相同,成员数量可以不确定。

数组有两种声明方式,类型后面加[]或者使用内置Array接口(下面会详细介绍接口interface)

let arr: number[] = [1, 2, 3];
let arr2: Array<number> = [1, 2, 3];

如果成员类型有不同类型,可以使用联合类型

let arr: (number | string)[] = [1, '阳阳羊', 3];
let arr2: Array<number | string> = [1, 2, '阳阳羊'];

类型推断

数组的类型推断与前文讲的有所不同,它会根据每个成员的类型而变化

如果没有声明数组类型,TS 会自动进行类型推断,当数组为空时,会推断为any类型的数组

快速上手 TS(进阶类型篇)今天我们来学习一下 TS 的进阶知识,数组、元组、函数、接口等等,具体可以参考目录,还是那句

当我们修改成员时,会自动进行更新。

这里我们push一个数字,会自动推断为number数组

快速上手 TS(进阶类型篇)今天我们来学习一下 TS 的进阶知识,数组、元组、函数、接口等等,具体可以参考目录,还是那句

我们再push一个字符串,自动推断成联合类型string | number的数组

快速上手 TS(进阶类型篇)今天我们来学习一下 TS 的进阶知识,数组、元组、函数、接口等等,具体可以参考目录,还是那句

元组

元组是 TS 新增的数据类型,它表示成员类型可以自由设置的数组。

const tuple: [string, number, boolean] = ["阳阳羊", 123, true];

写法上与数组有所不同,数组的类型是写在[]的左边,而元组的类型是写在[]内部。

使用元组时必须给出类型声明,不然会被 TS 自动推断为数组

快速上手 TS(进阶类型篇)今天我们来学习一下 TS 的进阶知识,数组、元组、函数、接口等等,具体可以参考目录,还是那句

?可选符

元组成员的类型可以添加问号后缀(?),表示该成员是可选的。

const tuple: [string, number, boolean?] = ["阳阳羊", 123];

需要注意的是可选成员要放在尾部,即所有可选成员必须在必选成员之后

如果放在前面会报错

快速上手 TS(进阶类型篇)今天我们来学习一下 TS 的进阶知识,数组、元组、函数、接口等等,具体可以参考目录,还是那句

...扩展运算符

一般情况下,元组的成员数量是固定的,有多少个类型声明就有多少个成员,但是...扩展运算符允许我们表示不定成员数量的元组。

const tuple: [string, ...number[]] = ["阳阳羊", 123, 456];

扩展运算符用在元组的任意位置都可以,但是只能扩展数组或元组。

函数

函数的类型声明,需要给出参数和返回值的类型

function fn(a: number, b: number): number {
    return a + b
}

这里两个参数ab类型都为number,以及返回值的类型number,返回值类型写在参数列表的圆括号后面。

我们也可以使用函数表达式进行声明

//方式一
const fn = function (a: number, b: number): number{
    return a + b
}
//方式二
const fn: (a: number, b: number) => number = function (a, b){
    return a + b
}

这里的两种方式都可以实现,第一种是通过等号右边来推断fn的类型,第二种则是直接指明了fn的类型。

返回值类型通常可以不写,TS 会自己推断出来,如果没写return语句,会推断为没有返回值

快速上手 TS(进阶类型篇)今天我们来学习一下 TS 的进阶知识,数组、元组、函数、接口等等,具体可以参考目录,还是那句

void 类型

void 类型表示函数没有返回值。如果你学过c语言,那你一定不会陌生。

在 TS 中void并不代表不能写return语句,它允许返回undefinednullnull需要关闭严格模式),因为它俩在 TS 看来也是相当于没有返回值。

function fn3(a: number, b: number):void{
    return undefined
}

但是如果你返回其它类型就会报错

function fn(a: number, b: number):void{
    return a + b //报错
}
快速上手 TS(进阶类型篇)今天我们来学习一下 TS 的进阶知识,数组、元组、函数、接口等等,具体可以参考目录,还是那句

函数重载

有些函数可以接受不同类型或不同个数的参数,并且根据参数的不同,会有不同的函数行为。这种根据参数类型不同,执行不同逻辑的行为,称为函数重载。

这里我们想实现一个函数,不管你传入的是数组还是字符串,我都希望它返回一个反转后的结果

reverse("abc"); // 'cba'
reverse([1, 2, 3]); // [3, 2, 1]

首先我们逐一定义每一种情况的类型

function reverse(str: string): string;
function reverse(arr: any[]): any[];

然后给予函数完整的类型声明

function reverse(stringOrArray: string | any[]): string | any[] {
  if (typeof stringOrArray === "string")
    return stringOrArray.split("").reverse().join("");
  else {
    return stringOrArray.slice().reverse();
  }
}

效果如下

console.log(reverse(["🐂","🐑","🐎", "🐒"])) //[ '🐒', '🐎', '🐑', '🐂' ]
console.log(reverse("牛羊马猴")) //猴马羊牛

type 命令

TS 允许我们用 type 来定义一个类型别名,我们习惯使用大驼峰命名方式进行命名。

type Name = string;
let name: Name = "阳阳羊";

这样Age就能像使用number一样作为类型来使用

别名不允许重名,拿值类型来举例

type Color = "红";
type Color = "绿"; //报错

如果一些类型定义很冗长,我们往往会用 type 命令为函数类型定义一个别名。

type MyFunc = (a: string) => void;

const fn: MyFunc = function (a) {
  console.log("hello " + a);
};

interface 接口

interface 是对象的模板,可以看作是一种类型约定,中文译为“接口”。使用了某个模板的对象,就拥有了指定的类型结构。

属性

interface Person {
  name: string;
  age: number;
}

这里我们定义了一个接口Person,两个属性nameage,任何实现这个接口的对象都必须具有这两个属性,并符合规定类型。

const me: Person = {
  name: "阳阳羊",
  age: 21
}

如果属性和类型有一个不符就会报错。

如果你希望属性是可选的,则可以使用?可选操作符,只读可以使用readonly修饰符

interface Person {
  name?: "阳阳羊",
  readonly age: 21
}

方法

除了属性外,接口还允许我们定义对象的方法

interface Person {
  say(x: string):string
}

函数

接口也可以用来声明独立的函数

interface Add {
  (x: number, y: number): number;
}
const myAdd: Add = (x, y) => x + y;

继承

接口可以使用extends关键字实现继承

interface Animal {
  name: string;
  age: number;
}

interface Dog extends Animal {
  color: string;
}

extends关键字会从继承的接口里面拷贝属性类型,这样就不必书写重复的属性

如果子接口与父接口存在同名属性,那么子接口的属性会覆盖父接口的属性。前提是不能有冲突,属性方法他们的类型得是一致的,不然会报错

interface Animal {
    name: string;
    age: number;
  }
  
interface Dog extends Animal {
  color: string;
  age: bigint;
}

这里存在同名属性,但是类型不一致

快速上手 TS(进阶类型篇)今天我们来学习一下 TS 的进阶知识,数组、元组、函数、接口等等,具体可以参考目录,还是那句

合并

多个同名接口会合并成一个接口

interface Box {
  height: number;
  width: number;
}

interface Box {
  length: number;
}

两个Box接口会合并成一个接口,同时有heightwidthlength三个属性。前提仍然是不能有冲突。

和 type 的区别

(1)type能够表示非对象类型,而interface只能表示对象类型(包括数组、函数等)。

(2)interface可以继承其他类型,type不支持继承。

(3)同名interface会自动合并,同名type则会报错。也就是说,TypeScript 不允许使用type多次定义同一个类型。

参考

最后

以上是对 TS 进阶类型的基本介绍,内容相对于基础,对于新同学来说比较友好,后面我会继续更新进阶知识,关于类、泛型、Enum 类型等等,可以关注加三连,我会持续更新。

已将学习代码上传至 github,欢迎大家学习指正!

技术小白记录学习过程,有错误或不解的地方还请评论区留言,如果这篇文章对你有所帮助请 “点赞 收藏+关注” ,感谢支持!!

转载自:https://juejin.cn/post/7386967785091629075
评论
请登录