TypeScript学习8:高级类型-交叉类型、联合类型

2019-10-11 admin

简介

此为高级类型的第一部分,学习交叉类型(Intersection Types)、联合类型(Union Types)以及在使用以上类型时如何区分具体类型。

交叉类型(Intersection Types)

交叉类型把几个类型的成员合并,形成一个拥有这几个类型所有成员的新类型。从字面上理解,可能会误认为是把取出几个类型交叉的(即交集)成员。

交叉类型的使用场景:Mixins、不适合用类来定义。

我感觉,交叉类型和Mixins有一点区别:交叉类型只是一个类型声明,用于类型约束;Mixins会给类增加成员,new对象时,对象会包含增加的成员属性。

我们看一看示例:

改自官方示例,官方示例有2个小问题:会提示不存在属性“hasOwnProperty”;另外,es6下prototype是不可以枚举的,无法通过枚举合并类属性。

  interface IAnyObject {
    [prop: string]: any
  }

  function extend<First extends IAnyObject, Second extends IAnyObject>(first: First, second: Second): First & Second {
    const result: Partial<First & Second> = {};
    for (const prop in first) {
      if (first.hasOwnProperty(prop)) {
        (result as First)[prop] = first[prop];
      }
    }
    for (const prop in second) {
      if (second.hasOwnProperty(prop)) {
        (result as Second)[prop] = second[prop];
      }
    }
    return result as First & Second;
  }

  interface IPerson {
    name: string,
    age: number
  }

  interface IOrdered {
    serialNo: number,
    getSerialNo(): number
  }

  const personA: IPerson = {
    name: 'Jim',
    age: 20
  }

  const orderOne: IOrdered = {
    serialNo: 1,
    getSerialNo: function () { return this.serialNo }
  }

  const personAOrdered = extend<IPerson, IOrdered>(personA, orderOne);
  console.log(personAOrdered.getSerialNo());
  • 其中First & Second就是交叉类型的写法。
  • 通过扩展,可以合并两传入对象的成员属性,增强现有对象的能力。

联合类型(Union Types)

联合类型与交叉类型类似,都可以拥有多个类型的能力,区别是:联合类型一次只能一种类型;而交叉类型每次都是多个类型的合并类型。

联合类型在实际项目中,使用场景比交叉类型广泛得多。

  1. 字符串填充:
  function padLeft(value: string, padding: number | string) {
    if (typeof padding === "number") {
      return Array(padding + 1).join(" ") + value;
    }
    if (typeof padding === "string") {
      return padding + value;
    }
    return value;
  }

  padLeft("Hello world", 4);
  1. 再举个常见的例子,常量的联合类型,五分制考试打分:
  type Scores = 1 | 2 | 3 | 4 | 5;

  function rating(score: Scores) {
    console.log(`Set score ${score}`);
  }

  rating(3);
  // error
  // rating(6); 

枚举也可以实现,但是这样更简洁。

  1. 还可以用于可为null的参数:
function f(sn: string | null): string {
    if (typeof sn === null) {
        return 'default';
    } else {
        return sn;
    }
}
  1. 还可以使用类型别名定义联合类型(上面场景2中用过):
type Method = 'get' | 'post';

类型保护和类型区分

使用联合类型时,我们是无法知道编译时的具体类型的,所以在运行时必须要确定类型。所以代码中需要做类型保护和类型区分。

为什么叫类型保护?因为在运行时,必须知道明确类型,否则可能会访问一个不存在的成员属性,导致程序出错。

  • 自定义类型保护

      // 先判断是否存在成员属性
      if(pet.swim) {
    
      }
    
  • in操作符

      // 先判断是否存在成员属性
      if('swim' in pet) {
    
      }
    
  • typeof操作符

    function f(sn: string | number): string {
        if (typeof sn === 'number') {
            return sn.toString();
        } else {
            return sn;
        }
    }
    
  • instanceof操作符

    // 判断实例原型
    if(pet instanceof Fish) {
    
    }
    
  • 类型断言

    function f(sn: string | null): string {
        if (sn === null) {
            return "default";
        } else {
            return sn;
        }
    }
    

联合类型应用极广泛,可以多实践。

[转载]原文链接:https://segmentfault.com/a/1190000020647981

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处。

转载请注明:文章转载自 JavaScript中文网 [https://www.javascriptcn.com]

本文地址:https://www.javascriptcn.com/read-77116.html

文章标题:TypeScript学习8:高级类型-交叉类型、联合类型

相关文章
es8
7 Abstract Operations 7 抽象操作 These operations are not a part of the ECMAScript language; they are defined here to solely...
2018-07-10
JavaScript数据类型判定的总结笔记
用typeof 来检测数据类型 Javascript自带两套类型:基本数据类型(undefined,string,null,boolean,function,object)和对象类型。 但是如果尝试用typeof 来检测对象类型都一律返回&...
2017-03-27
javascript获取本机操作系统类型的方法
废话不多说了,下面通过一段代码示例介绍一下,希望能够给需要的朋友带来或多或少的帮助。 示例代码: function GetOSInfo() { var _pf=navigator.platform; var appVer=navig...
2017-03-29
javascript制作2048游戏
2048.html &lt;!DOCTYPE&gt; &lt;html xmlns=&quot;http:&#x2F;&#x2F;www.w3.org&#x2F;1999&#x2F;xhtml&quot;&gt; &lt;head&gt; ...
2017-03-22
当 Egg.js 遇上 Typescript
# 前言 TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. TypeScript 的静态类型检查,智能提示,IDE 友好性等特...
2018-04-14
javascript中Function类型详解
Function 类型 function类型,毋庸置疑是js中相当重要的一个玩意。 1.这玩意首先是一个对象,也就是说它是一个引用类型。陈述:一听说是对象,是不是很有一种它的基类是object对象错觉感,No, 它和object是独立的2个...
2017-03-23
vant-ui学习手册
备注:红色部分为前端人员课程 项目搭建(1小时) 学习如何快速搭建并跑起项目 git下载 npm本地依赖安装 npm i webpack基本配置 根目录vue.config文件,请根据官方链接进行配置. 这里列举几个常用的...
2019-04-03
使用 TypeScript 构建 Koa2 项目的最佳实践
the best practice of building Koa2 with TypeScript. 中文 usage clone repo. git clone git@github.com:DhyanaChina/koa2-type...
2018-02-27
AngularJS基础学习笔记之指令
AngularJS通过指令将HTML属性进行了扩展。 AngularJS指令 AngularJS指令是带有ng-前缀的扩展HTML属性。 ng-app指令用来初始化AngularJS application。 ng-init指令用来初始化a...
2017-03-23
js表格排序实例分析(支持int,float,date,string四种数据类型)
本文实例讲述了js表格排序的方法。分享给大家供大家参考。具体如下: &lt;html&gt; &lt;head&gt; &lt;title&gt;SortTable2&lt;&#x2F;title&gt; &lt;meta http-equ...
2017-03-23
回到顶部