never类型

typescript的never类型代表永不存在的值的类型,它只能被赋值为never

任意类型与never交叉都得到never

type T1 = number & never;   // never
type T2 = string & never;   // never
复制代码

可以这样理解:若type T = T1 & T2,则T类型的值可以赋给T1T2类型的变量(类似类的继承关系)。 那么若与never交叉,则T类型的值可以赋给一个never类型的变量,那T只能是never了。

任意类型与never联合不受影响:

type T1 = number | never;   // number
type T2 = string | never;   // string
复制代码

理解与上述交叉类型情况类似: 若type T = T1 | T2,则T1T2类型的值可以赋给T类型的变量。 由于never类型可以赋给任意变量,自然对联合类型不产生影响了。

keyof

typescript的keyof关键字,将一个类型映射为它所有成员名称的联合类型。如typescript官网上的示例:

interface Person {name: string;age: number;location: string;
}type K1 = keyof Person; // "name" | "age" | "location"
type K2 = keyof Person[];  // "length" | "push" | "pop" | "concat" | ...
type K3 = keyof { [x: string]: Person };  // string
复制代码

keyof实际给我们一个操作联合类型的途径。结合typescript的其他feature,如类型映射与索引类型,我们得以在对象类型与联合类型之间游刃有余地转换,为工程中更多变量找到最适合的类型归属。

应用

Diff Type

我们看一个来自这里的例子:

type Diff<T extends string, U extends string> = ({ [P in T]: P } & { [P in U]: never })[T];
type Omit<T, K extends keyof T> = Pick<T, Diff<keyof T, K>>;
复制代码

下面一行不用过多解释了,在T类型中除去成员名在K中的成员。而上面一行代码特别有意思,也特别难看懂,它所做的是对于T与U两个字符串字面量类型,从T中除去包含在U中的那些字符串:

type A = Diff<"a" | "b" | "c", "a">;        // "b" | "c"
type B = Diff<"a" | "b" | "c", "b" | "d">;  // "a" | "c"
复制代码

它是如何做到的呢?我们首先看它的前面部分:

type FirstHalf<T extends string, U extends string> = { [P in T]: P } & { [P in U]: never }
type C = FirstHalf<"a" | "b" | "c", "b" | "d">;
// {//      "a": "a",
//      "b": "b",
//      "c": "c"
// } & {//      "b": never,
//      "d": never
// }
复制代码

我们再将type C做逐成员的交叉:

type C = {"a": "a","b": "b" & never,"c": "c","d": never
}
复制代码

任意类型与never交叉的结果都是never,因此

type C = {"a": "a","b": never,"c": "c","d": never
}复制代码

我们再看Diff类型:


type B = Diff<"a" | "b" | "c", "b" | "d">;= {"a": "a","b": never,"c": "c","d": never}["a" | "b" | "c"];= "a" | never | "c";= "a" | "c";
复制代码

这样就达到了前文所述的目的。

去除所有never成员

我们试图移除一个object type中所有类型为never的成员。可以这样操作:

type OmitNever<T> = Pick<T, {[P in keyof T]: T[P] extends never ? never : P}[keyof T]>;type T = {a: string,b: never,c: string,
}
type T1 = OmitNever<T>;     // { a: string, c: string }
复制代码

原理类似第一个例子。我们试图把T中所有非never成员的名称找出,从Tpick出来。所以先弄一个对象类型出来:

type OmitNeverHalf<T> = {[P in keyof T]: T[P] extends never ? never : P}type TT = OmitNeverHalf<T>;
// {
//     "a": "a",
//     "b": never,
//     "c": "c"
// }
复制代码

再用keyof T做一个索引类型,把对象类型变成联合类型,就得到了我们想要的那些成员名称。

转载于:https://juejin.im/post/5cb96c65e51d4578c35e7287

typescript:never与keyof的妙用相关推荐

  1. typescript 中的keyof、 in

    原文链接:https://juejin.cn/post/6844904145732763655#heading-0 keyof 定义 keyof与Object.keys略有相似,只是 keyof 是取 ...

  2. typescript typeof 和 keyof

    引言 很多人一看到typeof,就会联想到js中的类型判断,但是在ts中也有typeof的使用,但是它可不是用来判断类型的哦,他的作用是可以在类型上下文中进行类型查询,并且只能对变量的类型或者属性查询 ...

  3. 一个 TypeScript keyof 泛型用法

    平时工作自认为有 Swift Rust 经验, 所以不需要看 TypeScript 泛型方面的应用, 总以为大同小异, 拒绝看文档学语言, 从我做起. 今日看到一个用上泛型的 pluck 函数 fun ...

  4. typescript 之 keyof

    keyof TypeScript 允许我们遍历某种类型的属性,并通过 keyof 操作符提取其属性的名称. 该操作符可以用于获取某种 类型 的所有键,其返回类型是 联合类型,简单的说,它是作用于类型的 ...

  5. typescript keyof 和 typeof 用法

    typeof 操作符可以用来获取一个变量或对象的类型 const states = {name: 1,block: () => {return '123'}, }同一个类型的数据,直接获取它的类 ...

  6. typescript的keyof的用法

    第一种:与接口一起用,返回联合类型 interface Person {name: string;age: number;location: string;}type K1=keyof Person; ...

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

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

  8. TypeScript 2.1中的类型运算 一个递归的Readonly泛型

    去年12月的 TypeScript 2.1 中加入了 keyof / Lookup Types / Mapped Types 等 (编译期的) 类型运算特性. 本文将介绍这些特性,并用这些特性实现一个 ...

  9. 可能是基于 Hooks 和 Typescript 最好的状态管理工具

    接上一篇:我理想中的状态管理工具 之前说,对于我个人来而言,理想的状态管理工具只需同时满足两个特点: 简单易用,并且适合中大型项目 完美地支持 Typescript 未能找到一个完美满足这两点的,所以 ...

最新文章

  1. 在Outlook中用VBA导出HTML格式邮件
  2. 从零开始一个http服务器(五)-模拟cgi
  3. 3DSlicer17:Logics
  4. JSON格式以及基本用法
  5. 二值图片连续区域检测
  6. Spring Boot 2.0 都更新了什么
  7. 撞库***:一场需要用户参与的持久战
  8. 如何为iPhone 5屏幕分辨率开发或迁移应用程序?
  9. linux下Oracle 相关命令
  10. Web系统测试Web安全性测试
  11. strcmp函数php,php strcmp函数怎么用?
  12. matlab宝典pdf,《MATLAB 宝典(第4版)》---- 优化.pdf
  13. vmware虚拟机共享文件夹设置(xp)
  14. Python 交通仿真建模(1)
  15. #使用SAS进行变量筛选、模型诊断、多元线性回归分析 #
  16. ipfs 存储目录结构
  17. Holt-Winters:三次指数平滑算法
  18. 人工智能安全(五)—梯度攻击
  19. python学习——主要的代码结构,模块和包
  20. 怎么登陆和退出MySQL

热门文章

  1. 阿里架构师,谈对技术架构的理解,以及架构师角色的思考
  2. 【计算机网络】数据链路层详解
  3. 美图秀秀2013年6月5日实习生招聘题目
  4. 超高频RFID服装供应链管理系统
  5. 【WLAN】Wi-Fi Direct 用户指南
  6. Tomcat长轮训原理解析
  7. 医咖会免费SPSS教程学习笔记—二元逻辑回归
  8. 分析显著性目标检测--Global Context-Aware Progressive Aggregation Network for Salient Object Detection
  9. Jira 和 Confluence 安装和使用
  10. 2021年资料员-岗位技能(资料员)考试APP及资料员-岗位技能(资料员)模拟考试题库