TypeScript中的联合类型使用示例详解

 更新时间:2023年08月11日 10:05:33   作者:艾艾  
这篇文章主要为大家介绍了TypeScript中的联合类型使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

一. TS类型系统有哪些运算

联合类型,以下是具体的例子,理解成集合的并集

type A1 = number;
type B1 = string;
type C1 = A1 | B1;
const c1: C1 = 42;
// 这种可以理解成集合的并集,但是他们没有交集
type A2 = { name: string };
// 这里要理解成 A2表示name为string的所有对象,比如{name: 'a', age: 14}, 它既可以有age也可以没age
type B2 = { age: number };
type C2 = A2 | B2;
const c2: C2 = {
  name: 'John',
  age: 18,
};
// 这种可以理解成两个集合的并集,并且他们有交集

二. 如何使用联合类型?

用的时候必须拆开,不然只能用number和string同时拥有的方法或者属性

这种缩小类型范围的过程我们叫做类型收窄(narrowing)

const f1 = (a: number | string) => {
  if (typeof a === 'number') {
    a.toFixed();
  } else {
    a.split(',');
  }
};

三. typeof的局限性

typeof 作用于数组对象,普通对象,日期对象,null都是返回object

四. 使用instanceof来区分类型

const f1 = (a: Date | Date[]) => {
  if (a instanceof Date) {
    a;
  } else {
    a;
  }
};

五. instanceof的缺点

不支持string,number,boolean等基本类型

我们可以将instanceof 和 typeof结合解决这个问题

const f1 = (a: Date | string | Date[]) => {
  if (typeof a === 'string') {
    a;
  } else if (a instanceof Date) {
    a;
  } else {
    a;
  }
};

不支持TS独有的类型,也就是那些会被擦除的类型

用in解决,但是这个方案也只能解决部分问题,比如无法区分两个函数

type Person = {
  name: string;
};
type Animal = {
  x: string;
};
const f1 = (a: Person | Animal) => {
  if('name' in a) {
    a
  } else if ('x' in a) {
    a
  } else {
    a
  }
}

ts官方文档上也介绍了一些收窄类型的方案

六. ts中的区分类型方法

以上所讲都是根据js中的方式来区分类型,接下来我们讨论下ts中的类型区分方法

类型谓词/类型判断 is, is的优点支持所有ts类型,is的缺点麻烦。

type Rect = {
  height: number;
  width: number;
};
type Circle = {
  center: [number, number];
  radius: number;
};
const f1 = (a: Rect | Circle) => {
  if (isRect(a)) {
    a;
  }
};
// 这里x is Rect就是类型谓词,用于收窄类型,写boolean不行,因为这里写boolean的话ts不知道boolean的含义是什么
function isRect(x: Rect | Circle): x is Rect {
  return 'height' in x && 'width' in x;
}

使用可辨别联合类型,加字段来表示,好处让复杂类型的收窄变成简单类型的对比

  • 可以使用这种方式的条件 T = A | B | C | D ...

A,B,C,D...有相同属性kind或其它

kind的类型是简单类型

各类型中的kind可区分

总结: 我们需要一个同名,可辨别的简单类型的key,这样的T类型我们称为可辨别联合类型

type Circle = { kind: 'Circle'; center: [number, number] };
type Square = { kind: 'Square'; sideLength: number };
// 两个联合起来的类型通过加上kind字段来进行判断类型
type Shape = Circle | Square;
const f1 = (a: string | number | Shape) => {
  if (typeof a === 'string') {
    a;
  } else if (typeof a === 'number') {
    a;
  } else if (a.kind === 'Circle') {
    a;
  } else {
    a;
  }
};

补充一个使用可辨别联合类型的场景

在react中我们会经常这样写,比如对一个用户增删改查

type Action =
  | { type: 'getUser'; id: string }
  | { type: 'createUser'; attributes: any }
  | { type: 'deleteUser'; id: string }
  | { type: 'updateUser'; attributes: any };

使用断言

type Circle = { kind: 'Circle'; center: [number, number] };
type Square = { kind: 'Square'; x: number };
type Shape = Circle | Square;
const f1 = (a: Shape) => {
  (a as Circle).center; // 这就是断言
};
f1({ kind: 'Circle', center: [1, 2] });

七. any是否是所有类型(除了never/unknown/any/void)的联合?为什么?

不是,因为一旦两个类型联合起来,只能用此两个类型共有的方法,而any可以使用所有类型的方法

const f1 = (a: number | string) => {
  a.toFixed(); // 会报错
  a.split(); // 会报错
  a.toString(); // 只能用number和string共有的方法
};
const f2 = (a: any) => {
  a.toFixed(); // 不会报错
  a.split(); // 不会报错
};

any有点像法外狂徒,ts绝大部分规则对any不生效

const f1 = (a: any) => {
  const b: never = a; // 会报错,这算是any唯一不能违反的规则
};

那么什么是所有类型(除了never/unknown/any/void)的联合

unknown,因为unknown可以收窄到任何类型,也就是说它是任何类型的联合

const f1 = (a: unknown) => {
 if(a instanceof Date) {
   a // Date
 }
 if(isPerson(a)) {
   a // Person
 }
}

以上就是TypeScript中的联合类型使用示例详解的详细内容,更多关于TypeScript联合类型的资料请关注脚本之家其它相关文章!

相关文章

  • TypeScript 泛型接口具体使用实战

    TypeScript 泛型接口具体使用实战

    这篇文章主要为大家介绍了TypeScript 泛型接口具体使用实战,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07
  • typescript快速上手的进阶类型与技术

    typescript快速上手的进阶类型与技术

    本文讲述了typescript开发的一些高级的类型与技术,算是对于基础知识点的补充,具体内容包括:比如元组、枚举类、接口、泛型相关概念等。虽说是进阶,但是内容不算多也并不难理解。
    2022-12-12
  • TypeScript保姆级基础教程

    TypeScript保姆级基础教程

    这篇文章主要为大家介绍了TypeScript保姆级基础教程示例详解,主要为大家介绍了typescript的类型,函数,对象,接口等基础示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助
    2022-07-07
  • TypeScript 类型级别示例介绍

    TypeScript 类型级别示例介绍

    这篇文章主要为大家介绍了TypeScript 类型级别示例介绍,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-02-02
  • d3-scale d3-scaleTime使用示例详解

    d3-scale d3-scaleTime使用示例详解

    这篇文章主要为大家介绍了d3-scale d3-scaleTime使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • ts 类型体操 Chainable Options 可链式选项示例详解

    ts 类型体操 Chainable Options 可链式选项示例详解

    这篇文章主要为大家介绍了ts 类型体操 Chainable Options 可链式选项示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • 数据结构Typescript之哈希表实现详解

    数据结构Typescript之哈希表实现详解

    这篇文章主要为大家介绍了数据结构Typescript之哈希表实现详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-01-01
  • DS-SDK封装ThreeJS的三维场景核心库Viewer

    DS-SDK封装ThreeJS的三维场景核心库Viewer

    这篇文章主要为大家介绍了基于DS-SDK封装ThreeJS的三维场景核心库Viewer封装示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-10-10
  • Nest框架中集成使用Swagger示例说明

    Nest框架中集成使用Swagger示例说明

    这篇文章主要为大家介绍了Nest框架中集成使用Swagger的示例说明,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • TypeScript类型编程中的extends和infer示例解析

    TypeScript类型编程中的extends和infer示例解析

    这篇文章主要为大家介绍了TypeScript类型编程中的extends和infer示例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-08-08

最新评论