1.认识类型收窄

function handleType(val: string | number){
	if(typeof val === 'string'){
		return val.length; // (parameter) val: string
	return val; // (parameter) val: number

这个代码看上去也许没有什么有意思的地方,但实际上,TypeScript 在背后做了很多东西。

TypeScript 要学着分析这些使用了静态类型的值在运行时的具体类型。目前 TypeScript 已经实现了比如 if/else 、三元运算符、循环、真值检查等情况下的类型分析。

在我们的 if 语句中,TypeScript 会认为 typeof val === 'string' 是一种特殊形式的代码,我们称之为类型保护 (type guard),TypeScript 会沿着执行时可能的路径,分析值在给定的位置上最具体的类型。

2.类型保护(type guards)

JavaScript 本身就提供了 typeof 操作符,可以返回运行时一个值的基本类型信息,会返回如下这些特定的字符串:

  • “string”
  • “number”
  • “bigInt”
  • “boolean”
  • “symbol”
  • “undefined”
  • “object”
  • “function”

typeof操作符在很多 JavaScript 库中都有着广泛的应用,而 TypeScript 已经可以做到理解并在不同的分支中将类型收窄。​在 TypeScript 中,检查typeof返回的值就是一种类型保护。

function getText(str: number | string): string {
    if (typeof str === "number") {
        return `${str} isNumber`; // (parameter) str: number
    } else {
        return `${str} isString`; // (parameter) str: string

3.等值收窄(Equality narrowing)

Typescript 也会使用 switch 语句和等值检查比如 =、!、==、!=,去收窄类型。比如:

function getText(a: string | boolean, b: string | null): void {
    if (a === b) {
        console.log(a);
        console.log(b);
        // (parameter) a: string
        // (parameter) b: string
    } else {
        console.log(a);
        console.log(b);
        // (parameter) a: string | boolean
        // (parameter) b: string | null

ts的分析可能是这样的:

  1. 判断ab是否完全相等
  2. 完全相等,string类型是ab唯一可能的相同类型。所以ab一定是 string 类型。​判断具体的字面量值也能让 TypeScript 正确的判断类型。
  3. 不等,那就各自安好,不再纠结了~

4.四、in 操作符收窄

JavaScript 中有一个 in 操作符可以判断一个对象是否有对应的属性名。TypeScript 也可以通过这个收窄类型。

type Dog = { ww: "1"; mm?: "2" };
type Cat = { mm: "1" };
function inDemo(animal: Dog | Cat): void {
    if ("ww" in animal) {
        console.log(animal); // (parameter) animal: Dog
    } else {
        console.log(animal); // (parameter) animal: Cat

通过 “ww” in animal中,我们可以推断出,animal一定是Dog类型,类型收窄。

而如果有可选属性,Ts也会检测出来:

type Dog = { ww: "1"; mm?: "2" };
type Cat = { mm: "1" };
function inDemo(animal: Dog | Cat): void {
    if ("mm" in animal) {
        console.log(animal); // (parameter) animal: Dog | Cat
    } else {
        console.log(animal); // (parameter) animal: Dog

mm 在 animal中是不能正确收窄的,但如果不在 animal 中,则可以推断出其是 Dog 类型。

5.instanceof 收窄

instanceof 也是一种类型保护,TypeScript 也可以通过识别 instanceof 正确的类型收窄:

function instanceofDemo(a: object | number): void {
    if (a instanceof String) {
        console.log(a);
        // (parameter) a: String
    } else {
        console.log(a);
        // (parameter) a: number | object

6.赋值语句(Assignments)

TypeScript 可以根据赋值语句的右值,正确的收窄左值。

let x = Math.random() > 0.5 ? "abc" : 123; // x: string | number
x = 1; // x: number
x = "1"; // let x: string

注意这些赋值语句都有有效的,即便我们已经将 x 改为 number 类型,但我们依然可以将其更改为 string 类型,这是因为 x 最初的声明为 string | number,赋值的时候只会根据正式的声明进行核对。​

本篇文章是《Typescript基础入门》第二篇,收窄是一组比较难理解的思路,这里仅提到部分常见的形式,一起共勉吧!

欢迎Star⭐️

内容简介: 本文档是Typescript 入门指南;Typescript 是微软开发的 Javascript 的超集,Typescript兼容Javascript,可以载入Javascript代码然后运行。Typescript与Javascript相比进步的地方 包括:加入注释,让编译器理解所支持的对象和函 资源太大,传百度网盘了,链接在附件中,有需要的同学自取。 为了让程序有价值,我们需要能够处理最简单的数据单元:数字,字符串,结构体,布尔值等。TypeScript支持与JavaScript几乎相同的数据类型,此外还提供了实用的枚举类型方便我们使用。我们提过使用var声明时,它不在乎你声明多少次;你只会得到1个。var x;var x;var x;在上面的例子里,所有x的声明实际上都引用一个相同的x,并且这是完全有效的代码。这经常会成为bug的来源。好的是,let声明就不会这么宽松了。let x = 10;let x = 20; 从JavaScript程序员的角度总结思考,循序渐进的理解TypeScript。 该资源包括: 1:TypeScript入门教程电子书2:BAT / TMD大厂面经3:百本前端开源电子书4:50张思维导图 本网站使用 本书是作者在学习后整理的学习笔记。 随着对TypeScript理解的加深和TypeScript社区的发展,本书也会发生相应的更新,欢迎大家 Collection。 发现文章内容有问题,可以直接在页面下方评论 对项目的建议,可以向作者反馈 欢迎直接提交pull-request参与贡献 为什么要写本书 TypeScript虽然有及其非官方,但它每一章都希望能详尽的描述一个概念,导致前面的章节就会包含很多后面才会学习到的内容,而有些本该一开始就了解如果是初学者,可能需要阅读多次才能理解。所以它更适合用于查阅,而不是学习。 与官方手册不同,本书着重于从JavaScript程序员的角度总结思考,循序渐进的理解TypeScript,希望能给大家一些帮助和启示。 由于一些知识点与官方手册重合度很高,本 介绍TypeScript类型收窄(Type Narrowing),包括typeof 类型保护、真值收窄、等值收窄、in 操作符收窄、赋值语句、控制流分析、可辨别联合、never、穷尽检查 在本文中,我们将学习各种收窄类型的方法。类型(narrowing)收窄是将类型从不太精确的类型推导为更精确的类型的过程。 让我们从一个简单的函数开始: function friends(input: string | number) { // code here 上面的函数可以接受一个数字或一个字符串。假设我们要根据 input 是数字还是字符串来执行不同的操作。在这种情况下,我们将使用 ... 声明一个string类型的变量val。 let val: string = 'val'; val = 1; // Type 'number' is not assignable to type 'string'. 因为number类型和string类型并不兼容,在string类型值出现的地方并不能使用number类型指完成替换,所以在TS世界中给string 作者: 高翔转发链接:https://mp.weixin.qq.com/s/0DZ2f1dZue8-BATX0FQpSQ前言在 2020 年的今天,TS 已经越来越火,不管是服务端(Node.js),还是前端框架(Angular、Vue3),都有越来越多的项目使用 TS 开发,作为前端程序员,TS 已经成为一项必不可少的技能,本文旨在介绍 TS 中的一些高级技巧,提高大家对这门语言更深层次的认知。... “字数:1737字阅读: 3 分钟大家好,今天和大家聊下让我曾经迷惑的两个TS类型:unknown 和 never,不知道大家有没有对其用法有所迷惑呢,好记性比不过烂笔头,为了让我不... 1 引言从@types/react源码中挖掘一些 Typescript 使用技巧吧。2 精读泛型 extends泛型可以指代可能的参数类型,但指代任意类型范围太模糊,当我们需要对参... 文章目录前言一、TS是什么?Ts是静态类型TypeScript 是弱类型二、安装TS1.引入库三、TS基础原始类型数组对象函数Dom和类型转换类接口//类的interface泛型泛型接口枚举类型收窄四、React 和Typescript 第一遍学习TS 一、TS是什么? 官方介绍:TypeScriptJavaScript 的超集,这意味着它可以完成 JavaScript 所做的所有事情,而且额外附带了一些能力。 Typed JavaScript at Any Scale. 它强调了 Type