TypeScript基础(四):接口,泛型

接口  interface

接口,就是约定、限制的意思。

说白了,就是如果你实现了这个接口,你就必须得是这个样子,你不能是别的。你要是别的,那我就不承认你是我接口的一员。

我们先来看一个例子:

A 就是我们实现的一个接口。它必须得是一个对象,并且必须有 2 个属性 x 和 y。

并且 x 和 y 的类型必须是 number。

然后我们在添加一个接口 B:

a.x 和 a.y 不会报错。但 a.z 会报错。

你必须得用它们两个的公有属性,都有的才行。

所以,接口,你可以理解为一种必须遵守的规范。

看到这里,是不是觉得有些眼熟?这不就是我们前面说的 type 吗?只不过换了个关键字而已。

其实 interface 和 type 在很大程度上面是有交界的,可以互换。

我们再来看一个例子:

这里需要注意下,它之所以不会报错。是因为数组也是对象

所以我们还得继续去规定:

那么,如果我们将 interface 换成 type 呢?

可以看到,一样不会报错。

其实 interface 根本就不是当类型用的,它真正的用法在于,需要我们把它用来实现

比如说现在有一个需求,我有一个数据,我要求它是可以转成字符串,然后再转回来的。

所以它里面应该会有 2 个方法:

一个 tostring 方法,没有任何参数,返回一个字符串出来。

一个 fromstring 方法,接收一个字符串作为参数,返回值是空。

然后我们可以用 implements 这个关键字实现一个接口

这样写,会报错。

这是因为我们并没有 tostring 和 fromstring 两个方法。

加上 tostring 和 fromstring 两个方法后,就不会报错了。

如果你实现了某个接口,那么你要做的就是:

必须得实现这个接口当中规定了的那些方法。这就是接口的含义。

那么接口到底能干什么呢?

interface 它是一种规范,这个规范的意义就在于,你如果实现了我这个东西,你就必须得有相应的动作。

比如说,你就得提供 tostring 和 fromstring 这两个东西,它们一定得有。

那它怎么使用呢?

比如我们现在有一个函数 sendToServer,它所接受的参数,只能有一种。

就是必须得实现了 serializeable 接口的东西。

可以看到,这样是没问题的。

因为我传入的参数是 UserData 的实例。一切都符合要求。

那么如果函数 sendToServer 的参数,我传入一个没有实现 serializeable 接口的对象呢?

这时候就会报错:说 UserData2 并没有实现这个 serializeable 接口。

那么我们的目的是什么呢?

我们平时调试 js,是让程序跑起来之后,这里点点,那里输入点什么。你得测试,不停的点,不停的去找问题。

但是这种方法可能会有遗漏,而且时间和成本消耗也比较大。

但是如果我们不用程序真的跑起来,只是编译期间就能找到这个问题,那不是最好的吗?

ts 给我们提供的,就是这种方法。

然后我们通过上面的例子,可以看到 implements 的用法其实和 extends 是有点像的。

那么它们之间又有什么区别呢?

implements 是实现一个接口,并且可以同时实现多个接口。

写法也比较简单,写在后面,用逗号隔开就行:

extends 它是用来继承的,并且只能继承一个类。

所以,如果我有很多东西想要去规范,那么我们用 implements 更合适。

接下来,我们来看下 ts 里面最受欢迎之一的,泛型

泛,指的是宽泛。意思是我不限定这个类型,你可以是任何类型

看到这里,是不是也觉得和前面一个东西特别像?any。

但是这里需要注意的是,不要将泛型和 any 搞混了。

我们先来看下泛型的基本用法:

class Calc<T> {
    a: T
    b: T
}

上面的 <T> 就是泛型

T 是一个类型,意味着你可以在里面用。a, b 都是 T 类型。

所以,说白了,泛型,就相当于把类型当参数传进去。

然后我们来看个例子:

可以看到,左边的 obj.a 和 obj.b 都是 number 类型是没有问题的。

而右边,我们将 obj.b 赋值成字符串,就会报错了。

所以,在 new Calc<number> 这个时候,我们就把它的类型限制住了。

这个和 any 是有区别的,any 是不限制类型。

泛型虽然说可以变成任何类型,但还是有限制的,你只能在我这个圈里面选,你不能选别的。

泛型可以用联合类型:

然后我们再来看一个例子:

可以看到,repeat<number> 和 Array<number> 有点像。

实际上在 ts 里面来说,数组 Array 就是一个泛型

平时的写法:
let arr = [12, 5]

稍微完善一点:
let arr:number[] = [12, 5]

完整写法:
let arr:Array<number> = new Array() 
或
let arr:Array<number> = new Array<number>() 

其实我们一般都是用的简写:let arr:number[] = [12, 5]。

泛型类:

我们先 add 了一个数字类型 12,又 add 了一个字符串类型 'abc'。

按照类型推测,这时候是应该报错的。但是程序却没有报错。为什么呢?

这是因为 ts 现在推测不出来它到底是什么类型了,这个比较复杂。

ts 能推测的,就是在初始化阶段。再往后,就不行了。

所以我们可以在初始化的时候,手动的来声明一下,规定它这个数组,只能存某一个类型。

这个时候,它就会报错了。

发布了61 篇原创文章 · 获赞 3 · 访问量 4363

猜你喜欢

转载自blog.csdn.net/weixin_43921436/article/details/104081508
今日推荐