聊聊TypeScript中的Interface

前言

大概半年之前学习了一下 TypeScript,那时候对其中的interfacetype就产生了疑问,它们具体有什么区别?比较火的一个讲解是这篇文章:Typescript 中的 interface 和 type 到底有什么区别,如果你现在去百度搜,到现在很多搜索结果都是这篇文章的内容,或者结论。这篇文章很不错,大家可以看看,但是有个点,我读完之后,可能仍然不清楚什么场景下应该用interface或者是type。🤔

现在最近在学 Golang,Golang 的 interface让我对 TypeScript 中的interface有了一些想法,个人想法不一定对,大家理性讨论~

明朝的剑?

可能大家会想,这不是 Golang 嘛,和 TypeScript 完全不是同一个语言啊。

我是这么认为的:不管是什么样的编程语言,遵循的编程思维应该是一致的,虽然可能会在语法使用上以及解决的问题类型上会有所差异,但这些差异性应该不会太大。

比如说在 C 语言中的数组类型,它单纯就是一个有序的元素序列,虽然在 JS 上加上了队列加栈的用法,导致他们有所不同。但是你可以发现他们的解决问题的出发点是一致的:都是用来存放一个有序元素列表。

同一个名词的东西 ,我不太相信在不同的编程语言中,还有着巨大差别的规范。试想下:我在 C 语言用 array 定于数组,跑到 JS、TS 中用 array 想定义数组时,JS、TS 却告诉我你定义的是一个 Map。很不合理不是么?

Go 中的interface

本小节用的代码都为 Golang,便于说明问题,如果有想跑示例的代码,可以去这里尝试下在线 Go 编程

定义

我先简单介绍一下 Go 是怎么定义interface的:

interface 是 golang 最重要的特性之一,Interface 类型可以定义一组方法,但是这些不需要实现。请注意:此处限定是一组方法,既然是方法,就不能是变量;而且是一组,表明可以有多个方法。

如何理解?

  1. interface是一种类型
  2. interface只关心方法

为什么会有 interface?

这里先说 2 个 Go 的背景:

  1. Go 也是有type的,也可以用于做interface类似的事情。
  2. Go 函数接受参数时,不能像 TS 那样使用 function(arg: string | number)来接受形参

基于背景 2,我们来思考一种场景,假如我们现在要出门旅行了,选择了一种交通工具出发,交通工具有汽车、飞机...,每种出发方式不同,基于这个场景,我们来写写代码。

import "fmt"

乍一看,好像没啥问题,完全不需要interface不是嘛?那么假如,现在不仅人要旅游,小动物们也要旅游,根据上述说的背景 2:Go的形参必须明确一种类型,我们该怎么解决?

type Bearfamily struct{

的确,我们能通过新增函数解决问题,但试想一下,如果出游家庭种类多了呢?比如说兔子一家,小鸟一家...

发现了吧,我们不能使用 type 解决这类问题,因此需要有interface,有兴趣的话可以简单看看 Go 中的用法,没兴趣的话我们可以进入下一节。

type goTravel interface{

TypeScript 中的interface

总结一下,在上一节中 Go 中的interface实际上主要解决的是两个问题

  1. 一些抽象的方法不好归在一个大类里面
  2. 在函数调用时,Go 的静态语言编译校验不允许多个类型

首先看看第一个问题,我举一个比较贴近生活的例子:

现在市场上有 N 个巨头公司:阿里、腾讯、头条等等等,其中阿里、腾讯有各自的支付系统。现在要做一个电商平台需要对接这些大厂的支付系统。

type alibaba = {

可以发现,阿里跟腾讯作为两个大巨头,我们虽然能将其再归为一个大类,里面塞支付手段,但其实不太合理,别忘了还有外国的厂商,比如苹果支付等。

那么在这种场景下,我们可以使用 interface

interface payment {  // 描述的是一类支付动作

可以看到把支付方法集合放到 interface 中,是比较容易扩展的,假如未来头条也开发了支付系统,除了老的支付方式外,还新增了刷抖音支付,那么我们只需要在 payment 中加入 payByTikTok 即可,而不需要在头条这个类型中加入以前的支付方式定义。

我们再看第二个问题,这个问题在 TypeScript 也存在,别看 TS 可以允许使用|来解决,但是类型一多,咱也顶不住呀,试想一下。

// bad

虽然上面讨论的两个问题,TypeScript 中都有别的途径去扩展解决,比如说 type 与 interface 扩展,泛型等等手段。

但或许也正是因为 TypeScript 提供的这些手段,降低了 TS 中 type 与 interface 的辨识度吧🤔。

总结

经过上述的对比,个人认为可以仿造 Go 的定义,将描述方法等行为定义成 interface,其他类型,如 int , object 等等,可以使用 type 去处理。

当然这也只是个人想法,实在分不清的情况下,我们遵循下面这个逻辑,也挺香的(手动滑稽)

如果不清楚什么时候用 interface/type,能用 interface 实现,就用 interface , 如果不能就用 type 。

原文链接:juejin.im

上一篇:webpack多页面打包实践
下一篇:前端可视化——SVG矢量图技术

相关推荐

官方社区

扫码加入 JavaScript 社区