前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Typescript中的复杂类型声明

Typescript中的复杂类型声明

作者头像
腾讯IVWEB团队
发布2020-06-28 00:28:46
7K1
发布2020-06-28 00:28:46
举报

Typescript为javascript加入了众多类型声明语法,灵活使用可使代码变得健壮,不严谨的类型声明会带来后期的维护麻烦。本篇假设读者已经学会ts的基础类型声明语法,包括typeinterfaceextends和泛型,在此基础上,聊一聊一些更加复杂的类型声明场景以及解决办法。

场景1:子集类型

假设你有一个Person类,声明如下:

代码语言:javascript
复制
class Person{
    name: string;
    score: number;
    advance: (score: number) => void;
}

Person类有两个实例属性和一个原型方法。现在,我们需要一个PersonBasicInfo类型,它只包含Person类的基本信息,不能包含方法,算是Person类型的子集,这在一些有权限限制的接口传值时会使用到。我们第一时间想到的是写一个这样的类型:

代码语言:javascript
复制
type PersonBaseInfo = {
    name: string;
    score: number;
}

这样的硬编码方式快速地解决了问题,但是,一旦Person类修改字段,我们同样需要修改一遍PersonBasicInfo,增加了维护的工作量。最好的办法是自动筛选出Person类中符合某一规则的属性,生成一个新的类型。怎么做到呢?我们先来学习一些基础知识:

映射类型和条件类型

首先,在vscode中新建一个.ts文件,键入代码let p = Readonly<Person>,按下ctrl(mac的cmd)键点击Readonly进入定义,会发现如下代码:

代码语言:javascript
复制
/**
 * Make all properties in T readonly
 */
type Readonly<T> = {
    readonly [P in keyof T]: T[P];
};

官方已经给出了很好的解释,Readonly由原有的T类型“映射”成一个新的类型,新类型继承T的所有属性并限制其只读。这类用到了keyof关键字的类型我们称之为”映射类型“。延伸地看一下,周围还有PickRecord等等类型声明的例子,读者可以统一看一遍,有利于之后的开发。

另一个我们需要用到的例子是条件类型Exclude,它的源码就位于Readonly的下方不远处(你可能需要将ts升级到2.8以上才能看到),源代码如下:

代码语言:javascript
复制
/**
 * Exclude from T those types that are assignable to U
 */
type Exclude<T, U> = T extends U ? never : T;

使用时,Exclude需要填入两个泛型类,当T继承自U的时候,结果等于never类型,当TU不相关时,结果等于T类型。我们需要特殊关注一下这个never类型,官方给出的解释是:

Programming language design does have a concept of bottom type that is a natural outcome as soon as you do code flow analysis. TypeScript does code flow analysis (

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 场景1:子集类型
    • 映射类型和条件类型
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档