typescript:never与keyof的妙用
never类型
typescript的never
类型代表永不存在的值的类型,它只能被赋值为never
。
任意类型与never
交叉都得到never
:
type T1 = number & never; // never
type T2 = string & never; // never
复制代码
可以这样理解:若type T = T1 & T2
,则T
类型的值可以赋给T1
或T2
类型的变量(类似类的继承关系)。 那么若与never
交叉,则T
类型的值可以赋给一个never
类型的变量,那T
只能是never
了。
任意类型与never
联合不受影响:
type T1 = number | never; // number
type T2 = string | never; // string
复制代码
理解与上述交叉类型情况类似: 若type T = T1 | T2
,则T1
或T2
类型的值可以赋给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
成员的名称找出,从T
中pick
出来。所以先弄一个对象类型出来:
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的妙用相关推荐
- typescript 中的keyof、 in
原文链接:https://juejin.cn/post/6844904145732763655#heading-0 keyof 定义 keyof与Object.keys略有相似,只是 keyof 是取 ...
- typescript typeof 和 keyof
引言 很多人一看到typeof,就会联想到js中的类型判断,但是在ts中也有typeof的使用,但是它可不是用来判断类型的哦,他的作用是可以在类型上下文中进行类型查询,并且只能对变量的类型或者属性查询 ...
- 一个 TypeScript keyof 泛型用法
平时工作自认为有 Swift Rust 经验, 所以不需要看 TypeScript 泛型方面的应用, 总以为大同小异, 拒绝看文档学语言, 从我做起. 今日看到一个用上泛型的 pluck 函数 fun ...
- typescript 之 keyof
keyof TypeScript 允许我们遍历某种类型的属性,并通过 keyof 操作符提取其属性的名称. 该操作符可以用于获取某种 类型 的所有键,其返回类型是 联合类型,简单的说,它是作用于类型的 ...
- typescript keyof 和 typeof 用法
typeof 操作符可以用来获取一个变量或对象的类型 const states = {name: 1,block: () => {return '123'}, }同一个类型的数据,直接获取它的类 ...
- typescript的keyof的用法
第一种:与接口一起用,返回联合类型 interface Person {name: string;age: number;location: string;}type K1=keyof Person; ...
- 使用TypeScript映射和条件类型使React组件更出色
by Deepu K Sasidharan 通过Deepu K Sasidharan 使用TypeScript映射和条件类型使React组件更出色 (Make your React component ...
- TypeScript 2.1中的类型运算 一个递归的Readonly泛型
去年12月的 TypeScript 2.1 中加入了 keyof / Lookup Types / Mapped Types 等 (编译期的) 类型运算特性. 本文将介绍这些特性,并用这些特性实现一个 ...
- 可能是基于 Hooks 和 Typescript 最好的状态管理工具
接上一篇:我理想中的状态管理工具 之前说,对于我个人来而言,理想的状态管理工具只需同时满足两个特点: 简单易用,并且适合中大型项目 完美地支持 Typescript 未能找到一个完美满足这两点的,所以 ...
最新文章
- 在Outlook中用VBA导出HTML格式邮件
- 从零开始一个http服务器(五)-模拟cgi
- 3DSlicer17:Logics
- JSON格式以及基本用法
- 二值图片连续区域检测
- Spring Boot 2.0 都更新了什么
- 撞库***:一场需要用户参与的持久战
- 如何为iPhone 5屏幕分辨率开发或迁移应用程序?
- linux下Oracle 相关命令
- Web系统测试Web安全性测试
- strcmp函数php,php strcmp函数怎么用?
- matlab宝典pdf,《MATLAB 宝典(第4版)》---- 优化.pdf
- vmware虚拟机共享文件夹设置(xp)
- Python 交通仿真建模(1)
- #使用SAS进行变量筛选、模型诊断、多元线性回归分析 #
- ipfs 存储目录结构
- Holt-Winters:三次指数平滑算法
- 人工智能安全(五)—梯度攻击
- python学习——主要的代码结构,模块和包
- 怎么登陆和退出MySQL
热门文章
- 阿里架构师,谈对技术架构的理解,以及架构师角色的思考
- 【计算机网络】数据链路层详解
- 美图秀秀2013年6月5日实习生招聘题目
- 超高频RFID服装供应链管理系统
- 【WLAN】Wi-Fi Direct 用户指南
- Tomcat长轮训原理解析
- 医咖会免费SPSS教程学习笔记—二元逻辑回归
- 分析显著性目标检测--Global Context-Aware Progressive Aggregation Network for Salient Object Detection
- Jira 和 Confluence 安装和使用
- 2021年资料员-岗位技能(资料员)考试APP及资料员-岗位技能(资料员)模拟考试题库