Advanced Types

Intersection Types

当 type 为对象时,联合 type 取他们的并集

type Admin = {name: string;privileges: string[];
};type Employee = {name: string;startDate: Date;
};type ElevatedEmployee = Admin & Employee;const e1: ElevatedEmployee = {name: "Fan",privileges: ["Admin"],startDate: new Date(),
};

当 type 为 Union 的时候,联合 type 取他们的交集

type Combinable = string | number;
type Numeric = number | boolean;type Unverisal = Combinable & Numeric; // type: number

More on Type Guard

有几种方法做类型守卫
第一种,使用 typeof

type Combinable = string | number;
type Numeric = number | boolean;type Unverisal = Combinable & Numeric; // type: numberconst add = (a: Combinable, b: Combinable) =>typeof a === "string" || typeof b === "string"? a.toString() + b.toString(): a + b;

第二种,在面对一个对象时,我们不知道这个属性在不在这个对象里,可以使用 in 关键字。

type Admin = {name: string;privileges: string[];
};type Employee = {name: string;startDate: Date;
};type UnknownEmployee = Admin | Employee;function printEmployeeInformation(emp: UnknownEmployee) {console.log("Name" + emp.name);if ("privileges" in emp) {console.log("Privileges: " + emp.privileges);}if ("startDate" in emp) {console.log("Start Date: " + emp.startDate);}
}printEmployeeInformation({ name: "Jack", startDate: new Date() });

第三种,如果是 Class 的联合,我们可以使用 instanceof 来判断是不是其中一个类的实例,来判断他有哪些属性和方法可用。

class Car {drive() {console.log("Driving...");}
}
class Truck {drive() {console.log("Driving a truck...0");}loadCargo(amount: number) {console.log("Loading cargo..." + amount);}
}type Vehicle = Car | Truck;
const v1 = new Car();
const v2 = new Truck();function useVehicle(vehicle: Vehicle) {vehicle.drive();if (vehicle instanceof Truck) {vehicle.loadCargo(1000);}
}
useVehicle(v1);
useVehicle(v2);

Discriminated Union

我们可以设置一个我们已经知道的,一定存在的属性,去做类型守卫,去检查我们正在使用的类型。

interface Bird {type: "bird";flyingSpeed: number;
}interface Horse {type: "horse";runningSpeed: number;
}type Animal = Bird | Horse;function moveAnimal(animal: Animal) {let speed;switch (animal.type) {case "bird":speed = animal.flyingSpeed;break;case "horse":speed = animal.runningSpeed;break;}console.log("Moving at speed: " + speed);
}moveAnimal({ type: "horse", runningSpeed: 100 });

这里我们赋予了明面上的 type,在实例化对象的时候,我们就要写清楚我们的 type。同时,switch 的时候不容易写错单词,因为 TypeScript 会自动帮我们检查,有哪些是可选的选项,帮助我们 Coding。

Type Casting

类型转换非常有用。有时候我们需要操作 dom 节点,这个时候会有一些问题,我们知道我们选择的 dom 节点时什么标签,TypeScript 不知道。

const paragraph1 = document.querySelector("p");

在这个例子中,如果我们看 paragraph1 的类型,可以看到是const paragraph1: HTMLParagraphElement,因为我们是直接按类型选择的,可是如果按 ID 做选择呢?

const paragraph2 = document.getElementById("message-output");

可以看到类型为**const paragraph2: HTMLElement,**这个时候 TypeScript 就只知道他是一个 HTML 元素,不知道他是 p 标签,只可以获取一些通用的属性,例如 text 等。
如果这是一个 input 标签呢?

const userInputElement = document.getElementById("user-input");userInputElement.value = "Hi!";

这个时候如果我们修改它的 value 是会报错的。因为 TypeScript 并不知道你具体是什么标签,至少 HTMLElement 上没有 value,所以我们需要高速 TypeScript,这是一个 Input 标签。

const userInputElement = <HTMLInputElement>(document.getElementById("user-input")
);
//------------------------------------------------------------------------------
const userInputElement = document.getElementById("user-input"
)! as HTMLInputElement;

可以有两种方法,一种是在前面加’<>',另一种这是使用 as 关键字,其中的’!'是告诉 TypeScript 这里不会为 null。

如果我们不确定这个元素会不会 null 可以做检查。

if (userInputElement) (userInputElement as HTMLInputElement).value = "Hi";

Index Properties

有时候我们不希望把 Interface 写的太死。我们知道它的键值对分别是什么 type,同时数量又是可选的,那就用[]括起来。

interface ErrorContainer {// eg. {email: 'Not a valid email', username: 'Must start with a character'}[props: string]: string;
}const errorBag: ErrorContainer = {email: "Not a valid email",username: "Must start with a character",
};

Function Overloads

函数重载。没有函数重载我们会遇到一些问题。

type Combinable = string | number;const add = (a: Combinable, b: Combinable) =>typeof a === "string" || typeof b === "string"? a.toString() + b.toString(): a + b;const addResult = add("Jack", "Du"); as string;result.split(' ')

在这个例子中,如果我们没有写明**as string,**是没有办法使用 split 的,会报错。因为 result 可能为 number,使用重载来说清楚每种情况的返回类型,可以是函数更易维护和好用。

function overloadAddFunc(a: number, b: number): number;
function overloadAddFunc(a: string, b: string): string;
function overloadAddFunc(a: number, b: string): string;
function overloadAddFunc(a: string, b: number): string;
function overloadAddFunc(a: Combinable, b: Combinable) {return typeof a === "string" || typeof b === "string"? a.toString() + b.toString(): a + b;
}const result = overloadAddFunc("Jack", "Du");result.split(" ");

不同的参数类型对于应不同的返回类型。这个时候我们使用 split 就会有提示而且不报错了。

Optional Chaining

如果我们有一个,来自后端或数据库或任何其他不确定来源的数据,如果在对象中我们需要某个属性,但是这里面还没有做填充,或者不知道什么原因没获取到。我们需要做判断以防报错。
在 JavaScript 中这样操作。

const fetchUserData = {id: "1",name: "Jack",//   job: { title: "CEO", description: "My own company" },
};console.log(fetchUserData.job && fetchUserData.job.title);

TypeScript 有更好的选择:Optional Chaining

console.log(fetchUserData?.job?.title);

'?'表面:如果有这个选项,就继续往下访问。类似于做了 if 检查。

Nullish Coalescing

有时候我们会获取用户的输入,例如 input,如果他没有输入我们就采取一个默认值。
在 JavaScript 中可以这样做:

// const userInput = undefined;
// const userInput = null;
const userInput = "";console.log(userInput || "DEFAULT");

需要注意的是:如果 userInput 为空字符串,仍然会输出 DEFAULT,因为会视为 false。如果我们只想在非 null 和 undefined 的情况下,输入’DEFAULT’,那么就使用??

// const userInput = undefined;
// const userInput = null;
const userInput = "";console.log(userInput ?? "DEFAULT");

这个时候,哪怕 userInput 为空字符串,也会输出,输出内容为空。

Advanced Types相关推荐

  1. 使用TypeScript映射和条件类型使React组件更出色

    by Deepu K Sasidharan 通过Deepu K Sasidharan 使用TypeScript映射和条件类型使React组件更出色 (Make your React component ...

  2. Java为什么不提供运算符重载?

    从C ++到Java,一个显而易见的未解决问题是Java为什么不包括运算符重载? 不是Complex a, b, c; a = b + c;吗Complex a, b, c; a = b + c; C ...

  3. C语言,C#,Java,JavaScript之强类型与弱类型

    奇葩的我今天想到一个坑爹的问题,都说Java是强类型的语言,JavaScript是弱类型的语言. 嗯嗯,那初学时候的C语言呢? 呵呵哒,突然觉得短路了.说Java是强类型的语言是因为遇到这样的情况: ...

  4. The Basics

    "Swift is a new programming language for iOS and OS X app development. Nonetheless, many parts ...

  5. TypeScript 里 interface 和 type 的区别

    StackOverflow 上的讨论链接 Interface vs Type alias in TypeScript 2.7 Differences Between Type Aliases and ...

  6. 转译和编译_10个有趣又能编译为JavaScript的语言,你用过哪些?

    点击上方"IT平头哥联盟",选择"置顶或者星标" 你的关注意义重大! 来源:https://www.sitepoint.com/ 现代应用相比普通的网页有不同的 ...

  7. typescript_如何掌握高级TypeScript模式

    typescript by Pierre-Antoine Mills 皮埃尔·安托万·米尔斯(Pierre-Antoine Mills) 如何掌握高级TypeScript模式 (How to mast ...

  8. angular技巧_提升Angular技能的5个技巧

    angular技巧 This summer me and Roman started a series of tweets with helpful tips and tricks about Ang ...

  9. 快速而深入地了解TypeScript及其类型

    by David Piepgrass 由David Piepgrass 快速而深入地了解TypeScript及其类型 (A quick yet in-depth tour of TypeScript ...

最新文章

  1. pip删除依赖、配置虚拟环境
  2. html怎么建边框,如何使用CSS创建多色边框?
  3. oracle查询使用or,查询视图,使用or就用不上索引
  4. 这是一个测试:测试博客在浏览器中是否可以显示数学内容以及代码格式
  5. 线性代数导论2——矩阵消元
  6. [转]mpvue中的小程序调用系统自带查看图片的功能
  7. 数据结构(终极线段树篇)
  8. 鸿蒙系统8月9日发布,8月9日,华为发布EMUI10.0系统+展示鸿蒙系统
  9. 手机海报模板,收藏就对了!
  10. (五)构建和训练深度伪造自动编码器
  11. linux 给权限命令,Linux小白实用命令--权限设置
  12. 刚刚,Facebook开源了星际争霸AI代码
  13. spark入门及环境搭建
  14. 从最新的ACL、NAACL和EMNLP中详解知识增强的语言预训练模型
  15. 办公软件 -- Office 365免费下载安装
  16. 安卓Android问卷调查系统app
  17. IDEA2019.3新版本 报错 Cannot resolve column 'ID'
  18. M1 Mac无法读取NTFS格式硬盘里的内容应该怎样操作?
  19. 唐玄奘:不要因为走得太远,而忘了为什么出发
  20. Excel表格×××号码如何一键提取性别、年龄、出生年月

热门文章

  1. JavaScript Continue语句
  2. python创意小作品-Python竟能画这么漂亮的花,帅呆了(代码分享)
  3. 如何在R语言中读取数据
  4. Android高工:okhttp原理详解,搞懂了直接去虐面试官
  5. vue用form上传图片_vue图片上传
  6. SIL,PL等基础概念简介
  7. 给大家说明。OGG 的最新版本Version 11.2.1.0.25 BLR 19358139– 1 September 2014
  8. c语言在linux下运行程序设计,如何在Linux下运行C语言程序
  9. oracle+分页很慢,oracle分页查询缓慢的情况
  10. 不同VLAN之间互相通信