初学者这样玩 TypeScript,迟早进大厂系列(第六期)
Posted 极客江南
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了初学者这样玩 TypeScript,迟早进大厂系列(第六期)相关的知识,希望对你有一定的参考价值。
极客江南: 一个对开发技术特别执着的程序员,对移动开发有着独到的见解和深入的研究,有着多年的ios、android、html5开发经验,对NativeApp、HybridApp、WebApp开发有着独到的见解和深入的研究, 除此之外还精通 javascript、AngularJS、 NodeJS 、Ajax、jQuery、Cordova、React Native等多种Web前端技术及Java、php等服务端技术。
初学者玩转 TypeScript系列,总计 10 期,本文为第 6 期,点赞、收藏、评论、关注、三连支持!
对于初学者来说,学习编程最害怕的就是,难。
那么,Typescript 是不是很难?
首先,我可以肯定地告诉你,你的焦虑是多余的。新手对学习新技术有很强的排斥心理,主要是因为基础不够扎实,然后自信心不够强。
1.可辨识联合
- 什么是可辨识联合
- 具有共同的可辨识特征。
- 一个类型别名, 包含了具有共同的可辨识特征的类型的联合。
interface Square {
kind: "square"; // 共同的可辨识特征
size: number;
}
interface Rectangle {
kind: "rectangle"; // 共同的可辨识特征
width: number;
height: number;
}
interface Circle {
kind: "circle"; // 共同的可辨识特征
radius: number;
}
/*
Shape就是一个可辨识联合
因为: 它的取值是一个联合
因为: 这个联合的每一个取值都有一个共同的可辨识特征
*/
type Shape = (Square | Rectangle | Circle);
function aera(s: Shape) {
switch (s.kind) {
case "square": return s.size * s.size;
case "rectangle": return s.width * s.height;
case "circle": return Math.PI * s.radius ** 2; // **是ES7中推出的幂运算符
}
}
2. 可辨识联合完整性检查
interface Square {
kind: "square"; // 共同的可辨识特征
size: number;
}
interface Rectangle {
kind: "rectangle"; // 共同的可辨识特征
width: number;
height: number;
}
interface Circle {
kind: "circle"; // 共同的可辨识特征
radius: number;
}
/*
Shape就是一个可辨识联合
因为: 它的取值是一个联合
因为: 这个联合的每一个取值都有一个共同的可辨识特征
* */
type Shape = (Square | Rectangle | Circle);
/*
在企业开发中如果相对可辨识联合的完整性进行检查, 那么我们可以使用
方式一: 给函数添加返回值 + 开启strictNullChecks
方式二: 添加default + never
* */
function MyNever(x: never):never {
throw new Error('可辨识联合处理不完整' + x);
}
function aera(s: Shape):number{
switch (s.kind) {
case "square": return s.size * s.size;
case "rectangle": return s.width * s.height;
case "circle": return Math.PI * s.radius ** 2; // **是ES7中推出的幂运算符
default:return MyNever(s)
}
}
3. 索引类型
// 通过[]索引类型访问操作符, 我们就能得到某个索引的类型
// class Person {
// name:string;
// age:number;
// }
// type MyType = Person['name'];
// 应用场景
// 需求: 获取指定对象, 部分属性的值, 放到数组中返回
/*
let obj = {
name:'lnj',
age:18,
gender:true
}
function getValues<T, K extends keyof T>(obj:T, keys:K[]):T[K][] {
let arr = [] as T[K][];
keys.forEach(key=>{
arr.push(obj[key]);
})
return arr;
}
let res = getValues(obj, ['name', 'age']);
console.log(res);
*/
// 索引访问操作符注意点
// 不会返回null/undefined/never类型
interface TestInterface {
a:string,
b:number,
c:boolean,
d:symbol,
e:null,
f:undefined,
g:never
}
type MyType = TestInterface[keyof TestInterface];
4. 映射类型
/*
1.什么是映射类型?
根据旧的类型创建出新的类型, 我们称之为映射类型
* */
/*
interface TestInterface1{
name:string,
age:number
}
interface TestInterface2 {
readonly name:string,
readonly age:number
}
*/
interface TestInterface1{
name:string,
age:number
}
interface TestInterface2{
readonly name?:string,
readonly age?:number
}
type ReadonlyTestInterface<T> = {
// [P in keyof T]作用: 遍历出指定类型所有的key, 添加到当前对象上
// readonly [P in keyof T]: T[P]
// readonly [P in keyof T]?: T[P]
-readonly [P in keyof T]-?: T[P]
}
type MyType = ReadonlyTestInterface<TestInterface2>
// 我们可以通过+/-来指定添加还是删除 只读和可选修饰符
// 由于生成只读属性和可选属性比较常用, 所以TS内部已经给我们提供了现成的实现
// Readonly / Partial
type MyType2 = Readonly<TestInterface1>
type MyType3 = Partial<TestInterface1>
type MyType4 = Partial<Readonly<TestInterface1>
5. 映射类型
-
什么是字面量?
字面量就是源代码中一个固定的值
例如数值字面量: 1,2,3,…
例如字符串字面量: ‘a’,‘abc’,… -
在TS中我们可以把字面量作为具体的类型来使用
当使用字面量作为具体类型时, 该类型的取值就必须是该字面量的值
type MyNum = 1;
let value1:MyNum = 1;
let value2:MyNum = 2;
// Pick映射类型
// 将原有类型中的部分内容映射到新类型中
/*
interface TestInterface {
name:string,
age:number
}
type MyType = Pick<TestInterface, 'name'>
*/
// Record映射类型
// 他会将一个类型的所有属性值都映射到另一个类型上并创造一个新的类型
type Animal = 'person' | 'dog' | 'cat';
interface TestInterface {
name:string;
age:number;
}
type MyType = Record<Animal, TestInterface>
let res:MyType = {
person:{
name:'zs',
age:18
},
dog:{
name:'wc',
age:3
},
cat:{
name:'mm',
age:2
}
}
6. 分布式条件类型
/*
1.条件类型(三目运算)
判断前面一个类型是否是后面一个类型或者继承于后面一个类型
如果是就返回第一个结果, 如果不是就返回第二个结果
语法: T extends U ? X : Y;
* */
// type MyType<T> = T extends string ? string : any;
// type res = MyType<boolean>
/*
2.分布式条件类型?
被检测类型是一个联合类型的时候, 该条件类型就被称之为分布式条件类型
*/
// type MyType<T> = T extends any ? T : never;
// type res = MyType<string | number | boolean>;
// 从T中剔除可以赋值给U的类型。 Exclude
// type MyType<T, U> = T extends U ? never : T;
// type res = MyType<string | number | boolean, number>
// type res = Exclude<string | number | boolean, number>
// 提取T中可以赋值给U的类型。 Extract
// type res = Extract<string | number | boolean, number | string>
// 从T中剔除null和undefined。 NonNullable
// type res = NonNullable<string | null | boolean | undefined>
// 获取函数返回值类型。 ReturnType
// type res = ReturnType<(()=>number)>
// 获取一个类的构造函数参数组成的元组类型。 ConstructorParameters
// class Person {
// constructor(name:string, age:number){}
// }
// type res = ConstructorParameters<typeof Person>;
// 获得函数的参数类型组成的元组类型。 Parameters
function say(name:string, age:number, gender:boolean) {
}
type res = Parameters<typeof say>;
码字不易,在线求个三连支持。
大家记得收藏前,先点个赞哦!好的文章值得被更多人看到。
推荐阅读:
最后,再多一句,粉丝顺口溜,关注江哥不迷路,带你编程上高速。
版权所有,请勿转载,转载请联系本人授权
以上是关于初学者这样玩 TypeScript,迟早进大厂系列(第六期)的主要内容,如果未能解决你的问题,请参考以下文章
初学者这样玩 TypeScript,迟早进大厂系列(第七期)
初学者这样玩 TypeScript,迟早进大厂系列(第八期)
初学者这样玩 TypeScript,迟早进大厂系列(第九期)
初学者这样玩 TypeScript,迟早进大厂系列(第六期)