网站app建站多少钱,做网站vi系统是什么,淘宝网 商务网站建设目的,百度账号登录中心今天继续来分享ts的相关概念#xff0c;枚举#xff0c;ts模块化#xff0c;接口和类型兼容性 ts的扩展类型#xff1a;类型别名#xff0c;枚举#xff0c;接口和类 枚举
基础概念
枚举通常用于约束某个变量的取值范围。当然字面量和联合类型配合使用#xff0c;也可…今天继续来分享ts的相关概念枚举ts模块化接口和类型兼容性 ts的扩展类型类型别名枚举接口和类 枚举
基础概念
枚举通常用于约束某个变量的取值范围。当然字面量和联合类型配合使用也可以达到同样的目标。
为什么使用枚举
但是使用字面量和联合联系会存在一个问题
逻辑含义和真实值容易混淆修改真实值的时候会产生大量的修改字面量类型不会进入编译结果
使用枚举的话就不会出现这种问题
如何定义枚举
/*
enum 枚举名{枚举字段1 值1,枚举字段2 值2,..
}
*///实例enum Gender {Male 帅哥,Female 美女}// 先生 女士 男 女 male femalelet gender: Gender;gender Gender.Male;gender Gender.Female;编译后的js代码
var Gender;
(function (Gender) {Gender[Male] \u5E05\u54E5;Gender[Female] \u7F8E\u5973;
})(Gender || (Gender {}));
// 先生 女士 男 女 male female
let gender;
gender Gender.Male;
gender Gender.Female;下面给个使用联合类型的例子
type Gender 男 | 女;
let g:Gender;g 女;
g 男;编译后的js代码
let g;
g 女;
g 男;可以非常清晰的看出枚举的好处会把枚举里的属性也编译到结果里面避免了代码里面大量的真实值。
枚举的规则
枚举的字段值可以是字符串或数字数字枚举的值会自动自增
enum Level {level1 : 1,level2,level3
}let l: Level Level.level1;
console.log(l)
l Level.level2;
console.log(l)
l Level.level3;
console.log(l)控制台输出结果
1
2
3被数字枚举约束的变量可以直接赋值为数字 数字枚举的编译结果 和 字符串枚举有差异
小练习
这里使用枚举来做测试
//权限
enum Permission {Read 1, //0001Write 2, //0010Create 4, //0100Delete 8 //1000
}//1.使用或运算组合权限
let p: Permission Permission.Read | Permission.Write;//这样p就具备read和write权限//2.判断是否拥有某个权限使用且运算两边都是1才为1
function hasPermisson(target: Permission, per: Permission) {return (target per) per;
}//3.如何删除某个权限
//通过异或运算相同取0不同取1
p p ^ Permission.Write;模块化
配置名称含义module设置编译结果中使用的模块化标准moduleResolution设置解析模块的模式noImplicitUseStrict编译结果中不包含use strictremoveComments编译结果移除注释noEmitOnError错误时不生成编译结果esModuleInterop启动es模块化交互非es模块导出 前端模块化标准ES6、commonjs、amd、umd、systemesnext TS中如何书写模块化语句
TS中导入和导出模块统一使用ES6的模块化标准
编译结果中的模块化
可配置
TS中的模块化在编译结果中
如果编译结果的模块化标准是ES6没有区别如果编译结果的模块化标准是commonjs导出的声明会变成exports的属性默认的导出会变成exports的default属性;
默认是用的es6语法
import fs from fs;
import myModule from ./myModule;如何在TS中书写commonjs模块化代码
如果想用commonjs语法的话需要在tsconfig.json里面配置
{compilerOptions: { //编译选项module: CommonJS, //配置编译目标使用的模块化标准},
}代码
//导出
export xxx//导入
import xxx require(xxx)示例
//modules.ts
export {name: kakarote,sum(a: number, b: number) {return a b;}
}//index.ts
import myModule require(./myModule);模块解析
关于ts的一个模块解析策略它有两种模块解析策略
具体可以查看中文网https://www.tslang.cn/docs/handbook/module-resolution.html也可以去官网里查看 classic:经典模块解析策 //一、对于相对路径引入的模块流程
//root/src/folder/A.ts
import { b } from ./moduleB//这样引入的话首先它会查找
//1. /root/src/folder/moduleB.ts
//2. /root/src/folder/moduleB.d.ts//二、对于非相对路径的导入
//编译器则会从包含导入文件的目录开始依次向上级目录遍历尝试定位匹配的声明文件。
//root/src/folder/A.ts
import { b } from moduleB
//它会这么查找
//1./root/src/folder/moduleB.ts
//2./root/src/folder/moduleB.d.ts
//3./root/src/moduleB.ts
//4./root/src/moduleB.d.ts
//5./root/moduleB.ts
//6./root/moduleB.d.ts
//7./moduleB.ts
//8./moduleB.d.tsnode模块解析策略 //一、对于相对路径引入的解析模块流程
///root/src/moduleA.js
var x require(./moduleB);//1.它会监测:/root/src/moduleB.js文件是否存在
//2.监测/root/src/moduleB目录是否包含package.json模块如果package.json指定了main模块包含了{ main: lib/mainModule.js }那么它就会引用/root/src/moduleB/lib/mainModule.js
//3.监测/root/src/moduleB目录是否包含index.js如果存在它就会被当做那个文件夹的main模块//二、非相对模块的解析流程
///root/src/moduleA.js
var x require(moduleB)//1./root/src/node_modules/moduleB.js
//2./root/src/node_modules/moduleB/package.json (如果指定了main属性)
//3./root/src/node_modules/moduleB/index.js//4./root/node_modules/moduleB.js
//5./root/node_modules/moduleB/package.json (如果指定了main属性)
//6.root/node_modules/moduleB/index.js//7./node_modules/moduleB.js
//8./node_modules/moduleB/package.json (如果指定了main属性)
//9./node_modules/moduleB/index.js注意Node.js在步骤4和7会向上跳一级目录。接口
TypeScript的接口用于约束类、对象、函数的契约标准
契约标准的形式 API文档弱标准 代码约束强标准
和类型别名一样接口不出现在编译结果中
接口约束对象
interface User {name: stringage: numbersayHello: () void
}//定义类型别名
// type User {
// name: string,
// age: number,
// sayHello: () void
// }let u: User {name: sdsad,age: 33,sayHello() {console.log(asdasdsasa)}
}接口可以继承
class Banner extends React.Component{}可以通过接口之间的继承实现多种接口的组合
使用类型别名可以实现类型的组合效果需要通过它叫做交叉类型
它们的区别
子接口不能覆盖父接口的成员交叉类型会把相同成员的类型进行交叉
readonly
只读修饰符修饰的目标是只读
只读修饰符不在编译结果中
类型兼容性
B-A如果能完成赋值,则B和A类型兼容
鸭子辨型法子结构辨型法目标类型需要某一些特征赋值类型只要能满足该特征即可
例子
interface Duck {sound: 嘎嘎嘎,swim(): void
}let person:Duck {name: 伪装成鸭子的人,age: 1,sound: 嘎嘎嘎 as 嘎嘎嘎,swim() {console.log(this.name 正在游泳并发出了 this.sound 的声音)}
}如果直接给person设置Duck类型约束会报错 但是可以使用下面这种方式
interface Duck {sound: 嘎嘎嘎,swim(): void
}let person {name: 伪装成鸭子的人,age: 1,sound: 嘎嘎嘎 as 嘎嘎嘎,swim() {console.log(this.name 正在游泳并发出了 this.sound 的声音)}
}let duck: Duck person;如果直接用对象的字面量形式就会报错但是赋值的形式它就会忽略只要有sound和swim就不会报错 函数类型
我们可以看到arr的forEach的一个函数的ts定义
forEach(callbackfn: (value: number, index: number, array: number[]) void, thisArg?: any): void它这里要求这个回调函数的参数有这些valueindexarray但是这里我们传递的时候可以少传递但是不能多传递。
[34, 3].forEach(it console.log(it));Tips
参数值传递给目标函数参数可以少不能多
返回值如果函数要求返回一定要返回不要求返回则可以随意
结语
今天的学习回顾就到这里了