TypeScript高级类型
交叉类型
将多个类型合并成一个类型,取两个类型的并集。与继承的区别是,继承可以有自己的属性,而交叉没有。
interface DogInterface {
run():void
}
interface CatInterface {
jump():void
}
let pet: DogInterface & CatInterface = { // 看上去和接口多继承很像,但有一点区别。继承可以有自己的属性,交叉不行。
run(){},
jump(){},
};
联合类型
声明的类型并不确定,可以是多个类型中的一个。
let a: number | string = "a"; // 类型限定
let b: "a" | "b" | "c"; // 限定取值
let c: 1 | 2 | 3 | "v"; // 限定取值
可区分的类型保护:
// 现在有两种形状,area函数用来计算每种形状的面积。
interface Square{
kind: "square";
size: number;
}
interface Rectangle{
kind: "rectangle",
width: number,
height: number,
}
type Shape = Square | Rectangle;
function area(s: Shape) {
switch (s.kind) {
case "square":
return s.size * s.size; // 此区块内,确保只有size属性
case "rectangle":
return s.height * s.width;
}
}
console.log(area({kind:"square",size:10})); // 100
// 现在要添加一个形状:圆形。需要定义接口Circle、为Shape添加联合类型Circle,然后为area函数内增加一个case。但是,如果我们忘了修改area函数,会发生什么?
interface Circle{
kind: "circle",
r: number,
}
type Shape = Square | Rectangle | Circle;
console.log(area({kind:"circle",r:10})); // undefined,这里并不报错,并不符合我们的预期。我们希望bug能够及时暴露出来,增加程序的稳定性。
做如下改动:
function area(s: Shape) {
switch (s.kind) {
case "square":
return s.size * s.size;
case "rectangle":
return s.height * s.width;
case "circle":
return Math.PI * s.r;
default:
return ((e: any)=>{throw new Error(`没有定义 ${s} 的面积计算方式`)})(s) // 这一步很重要,一定要在这里抛出异常
}
}
索引类型
当我们使用不存在的索引时,会返回undefined,没有约束(如下代码)。因此我们需要有对索引的约束。
let obj = {
a: 1,
b: 2,
c: 3,
};
function getValue(obj: any,keys: string[]){
return keys.map(key => obj[key]);
}
console.log(getValue(obj,["a","b"]));
console.log(getValue(obj,["c","f"])); // 会发现,'f'对应的输出是undefined,没有约束,需要用到索引类型
下面使用索引类型:
function getValue<T,K extends keyof T>(obj: T, keys: K[]): T[K][] { // T[k][]表示,返回值必须是obj中的值组成的列表
return keys.map(key => obj[key]); // 此时keys中的元素只能是obj中的键
}
console.log(getValue(obj,["a","b"]));
console.log(getValue(obj,["c","f"])); // 这时就会报错,有了约束 'f' is not in "a" | "b" | "c"
我们来解释一下:
这里会用到两个操作符,查询操作符 keyof T 和 访问操作符 T[k](看下面示例)。<T, K extends keyof T> 用到了泛型约束,表示K所约束的参数的值只能是T所约束参数数据中的“键”。
// keyof T
interface Obj{
a: number;
b: string;
}
let key: keyof Obj; // 此时key表示 'a' | 'b' // T[k]
let value: Obj['a'] // number
映射类型
可以从旧的类型生成新的类型。比如,将接口中的所有成员变成只读、可选。
TS内置了很多映射类型。
interface Obj{
a: string;
b: number;
c: boolean;
}
// 将Obj接口中每个成员变成只读属性,生成一个新的接口。
type ReadonlyObj = Readonly<Obj>; // Readonly是TS内置的映射类型,下同
// Readonly实现原理,利用了索引类型的操作方法
type Readonly<T> = {
readonly [P in keyof T]: T[P];
}
再如:
// 将所有属性变成可选
type PartialObj = Partial<Obj>;
// Partial实现原理
type Partial<T> = {
[P in keyof T]?: T[P];
} // 获取原类型的子集
type PickObj = Pick<Obj,'a'|'b'>;
// 等同于
interface PickObj {
a: string,
b: number
} // 将原类型当做新类型的成员
type RecordObj = Record<'x'|'y',Obj>;
// 等同于
interface RecordObj {
x: Obj,
y: Obj,
}
沙发
条件类型
条件类型指由表达式所决定的类型。条件类型使类型具有了不唯一性,增加了语言的灵活性。
例如:
T extends U ? X : Y 表示如果类型T可以被赋值给类型U,name结果就赋予X类型,否则赋予Y类型
再如:
type TypeName<T> =
T extends string ? string :
T extends number ? number :
T extends boolean ? boolean :
T extends undefined ? undefined :
T extends Function ? Function :
object; type T1 = TypeName<string>; // T1为字符串类型
type T2 = TypeName<string[]>; // T2为object类型
type T3 = TypeName<Function>; // T3为function类型
type T4 = TypeName<string | string[]>; // T4为 string和object的联合类型
可以用来做什么?
(A | B) extends U ? X : Y
解析为(A extends U ? X : Y) | (B extends U ? X : Y)
可以利用这一特性做类型的过滤,例如:
type Diff<T,U> = T extends U ? never : T; type T5 = Diff< 'a'|'b'|'c', 'a'|'e' >; // 作用是过滤掉第一个参数中的'a' 。T5为 'b' | 'c'联合类型
解析过程:
Diff<'a', 'a'|'e'> | Diff<'b', 'a'|'e'> | Diff<'c', 'a'|'e'>
never | 'b' | 'c'
'b' | 'c'
TS内置的条件类型:
Exclude<T, U> // 从T中剔除可以赋值给U的类型,相当于上面例子中的Diff
Extract<T, U> // 提取T中可以赋值给U的类型。
NonNullable<T> // 从T中剔除null和undefined。
ReturnType<T> // 获取函数返回值类型。
InstanceType<T> // 获取构造函数类型的实例类型。
TypeScript高级类型的更多相关文章
- C# vs TypeScript - 高级类型
总目录 从C#到TypeScript - 类型 从C#到TypeScript - 高级类型 从C#到TypeScript - 变量 从C#到TypeScript - 接口 从C#到TypeScript ...
- 从C#到TypeScript - 高级类型
C# vs TypeScript - 高级类型 上一篇讲了基础类型,基本上用基础类型足够开发了,不过如果要更高效的开发,还是要看下高级类型,这篇和C#共同点并不多,只是延用这个主题. 联合类型 可以从 ...
- Typescript高级类型与泛型难点详解
最近做的TS分享,到了高级类型这一块.通过琢磨和实验还是挖掘出了一些深层的东西,在此处做一下记录,也分享给各位热爱前端的小伙伴. 其实在学习TS之前就要明确以下几点: 1. typescrip ...
- TypeScript 高级类型
⒈交叉类型(Intersection Types) 交叉类型是将多个类型合并为一个类型. 这让我们可以把现有的多种类型叠加到一起成为一种类型,它包含了所需的所有类型的特性. 例如, Person &a ...
- TypeScript 高级类型 接口(interface)
在代码的实现或者调用上能设定一定的限制和规范,就像契约一样.通常,我们把这种契约称为接口. TypeScript的核心原则之一是对值所具有的结构进行类型检查. 有时称为“鸭式辨型法”或“结构性子类型化 ...
- TypeScript 高级类型 类(class)
传统的JavaScript程序使用函数和基于原型的继承来创建可重用的组件,但对于熟悉使用面向对象方式的程序员来讲就有些棘手,因为他们用的是基于类的继承并且对象是由类构建出来的. 从ECMAScript ...
- TypeScript入门-高级类型
高级类型 交叉类型 交叉类型,就是将多个类型合并为一个新的类型,这个新的类型具有这多个类型的成员,含有这几个类型的所有特性,是他们的综合体,像是集合的并集 例子: function extend< ...
- typescript枚举,类型推论,类型兼容性,高级类型,Symbols(学习笔记非干货)
枚举部分 Enumeration part 使用枚举我们可以定义一些有名字的数字常量. 枚举通过 enum关键字来定义. Using enumerations, we can define some ...
- TypeScript 之 基础类型、高级类型
基础类型:https://m.runoob.com/manual/gitbook/TypeScript/_book/doc/handbook/Basic%20Types.html 高级类型:https ...
随机推荐
- dom4j处理带命名空间的XML-使用XPath(转)
dom4j处理带命名空间的XML-使用XPath 博客分类: XML XPath 是一门在 XML 文档中查找信息的语言.XPath 可用来在 XML 文档中对元素和属性进行遍历. XPath 使 ...
- linux crontab定时任务运行shell脚本(shell执行sql文件)
https://www.cnblogs.com/tiankongjava/p/6106743.html 今天做个linux定时任务(每晚12点把表汇总). 顺便写个博客记录一下~~ 为什么用linux ...
- [转]8天玩转并行开发——第二天 Task的使用
在我们了解Task之前,如果我们要使用多核的功能可能就会自己来开线程,然而这种线程模型在.net 4.0之后被一种称为基于 “任务的编程模型”所冲击,因为task会比thread具有更小的性能开销,不 ...
- 阿里云 Aliplayer高级功能介绍(五):多语言
基本介绍 Aliplayer默认支持中文和英文,并且依赖于浏览器的语言设置自动启用中文或英文资源, 除了支持这两种资源外,还提供自定义语言的形式,支持其他国际语言,另外Aliplayer还支持点播服务 ...
- 在 Angularjs 中$state.go 如何传递参数
在目标页面规定接受的参数: .state('app.AttendanceEditFixed', { url: '/AttendanceEditFixed', params: {'id': null,' ...
- python进阶_浅谈面向对象进阶
python进阶_浅谈面向对象进阶 学了面向对象三大特性继承,多态,封装.今天我们看看面向对象的一些进阶内容,反射和一些类的内置函数. 一.isinstance和issubclass class F ...
- jeecms 前台拦截器的研究与改造
jeecms 前台拦截器的研究与改造 2013年12月24日 15:23:35 xinfei0803 阅读数 3511 jeecms出发点是面向大众的,具有前台开发性,也就是说,即时是未登录(游客 ...
- 用wix制作属于自己的Flash网站
Wix 制作属于自己的Flash网站 Wix 是一款新兴的在线应用程序,它可以帮助用户轻松的创建出绘声绘色的Flash网站,而不需要任何相关的专业知识.Wix 是一家位于以色列的Startup开发的一 ...
- 第一个SpringBoot插件-捕获请求并且支持重新发起
SpringBoot 插件入门 简介 公司用的是SpringBoot,api框架用的是swagger-ui,确实用的不错,但是在使用过程中发现一个问题,就是当前端正式调用的时候,如果参数一多的话模拟请 ...
- Python移动自动化测试面试
Python移动自动化测试面试 整个课程都看完了,这个课程的分享可以往下看,下面有链接,之前做java开发也做了一些年头,也分享下自己看这个视频的感受,单论单个知识点课程本身没问题,大家看的时候可以关 ...