typescript学习回顾(三)

今天继续来分享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 strict"
removeComments编译结果移除注释
noEmitOnError错误时不生成编译结果
esModuleInterop启动es模块化交互非es模块导出

前端模块化标准:ES6、commonjs、amd、umd、system,esnext

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.ts
    
  • node:模块解析策略

    //一、对于相对路径引入的解析模块流程
    ///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

它这里要求这个回调函数的参数有这些,value,index,array,但是这里我们传递的时候可以少传递,但是不能多传递。

[34, 3].forEach(it => console.log(it));

Tips:

参数值:传递给目标函数参数可以少,不能多

返回值:如果函数要求返回一定要返回,不要求返回则可以随意

结语

今天的学习回顾就到这里了!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/38749.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis 配置详解

文章目录 Redis 配置详解网络持久化复制安全客户端内存管理延迟释放仅追加模式LUA集群慢指令延迟监控事件通知高级配置主动碎片整理 Redis 配置详解 网络 ########################## NETWORK ########################## bind:指定 Redis 只接收来自于特定 IP 地…

Linux 高级编程——线程控制

线程控制:互斥与同步 概念: 互斥 》在多线程中对临界资源的排他性访问。 互斥机制 》互斥锁 》保证临界资源的 访问控制。 pthread_mutex_t mutex; 互斥锁类型 互斥锁变量 内核对象 框架: 定义互斥锁 》初始化锁 》加…

前端——在本地搭建Vue单页应用

目录 1、安装最新node.js 2、打开命令行窗口 3、进入要保存项目的目录下 4、安装 Vue CLI 5、创建新项目,选择功能 5.1 新建项目 5.2 Please pick a preset 5.3 Check the features needed for your project 5.4 Choose a version of Vue.js 5.5 Use hist…

Android13 串口控制是能wifi adb实现

Android13 串口控制是能wifi adb实现 文章目录 一、前言二、Android 串口控制是能wifi adb实现1、通过Settings属性控制2、通过prop属性控制3、wifi adb 对应的Settings属性和prop属性关系(1)属性监听(2)相关代码位置(…

优化数据库字段使用位运算-php语言示例

背景:一个会员有三个状态,A、B、C,其中一个人可以为 A、B、C、AB;之前数据表结构加了三个字段is_a、is_b、is_c; 本人实在不想这样粗糙的实现需求,遂决定用位运算优化。 上代码: 位运算可以用来处理状态值…

探索SOLIDWORKS 2024设计增强功能

随着技术的不断进步和市场的日益竞争,工程设计和制造行业对于快捷、准确和创新的工具需求日益增长。SOLIDWORKS作为3D CAD设计软件,一直致力于为用户提供更强大、更便捷的设计工具。SOLIDWORKS 2024的发布,再次证明了其在设计增强功能方面的持…

使用 Amazon Bedrock Converse API 简化大语言模型交互

本文将介绍如何使用 Amazon Bedrock 最新推出的 Converse API,来简化与各种大型语言模型的交互。该 API 提供了一致的接口,可以无缝调用各种大型模型,从而消除了需要自己编写复杂辅助功能函数的重复性工作。文中示例将展示它相比于以前针对每…

如何在Windows上使用Docker搭建PHP开发环境

前言 在本地搭建开发环境我好像没几年就要折腾一次,因为本地开发电脑使用的是windows,早些年的时候,用过很多类似WAMP之类的东西,但最终都有或多或少不满意的地方,前两年的时候,还折腾过WSL,但…

批量文件名修改软件:一键解决同一编码多型号文件分类与命名难题,高效管理文件

在数字化时代,图片文件已经成为我们工作中不可或缺的一部分。然而,当面对成百上千个同一编码下不同型号的图片文件时,如何快速、准确地进行分类和命名,成为了许多职场人士头疼的问题。现在,我们为您带来了一款神奇的批…

MyBatisPlus 基础数据表的增删改查 入门 简单查询

MyBatisPlus MyBatisPlus(简称MP)是一个基于MyBatis的增强工具库,简化了MyBatis的开发,提供了很多实用的功能和特性,如自动生成SQL、通用CRUD操作、分页插件、条件构造器、代码生成器等。它不仅简化了开发过程&#x…

2024海亮日记

写在前面:长文预警 20240617 听说要去海亮,不考(补考)期末考试,于是进行一个停课的办理,第一次进入410,被逆天的配置和气氛所震惊 发誓这回去HL一定要有好效果,于是制定了详细的计…

golang 未指定类型interface{} 类型的 int类型数据json.Unmarshal 解码后变成float64类型问题解决方法

golang内置的json反序列化方法,默认情况下对应 未指定类型interface{} 类型的的 int类型数据在经过Unmarshal解码后 int类型的数据会变成 float64类型。 因为json里面默认将interface{}类型的int数据都当做float64来处理。 解决方法很简单,就是使用自定…

优盘有盘符显示0字节:故障解析与数据恢复策略

一、优盘有盘符显示0字节现象描述 在使用优盘的过程中,我们有时会遇到一种令人困惑的情况:插入优盘后,电脑能正常识别到优盘的盘符,但当我们尝试访问其中的数据时,却发现优盘的容量显示为0字节,无法读取或…

快速掌握MyBatis

MyBatis 是一个流行的 Java 持久层框架,它提供了一种半自动的 SQL 映射方式,使得开发者能够更加灵活地编写 SQL 语句,同时避免了传统 JDBC 代码的冗余和复杂性。下面进行简要概述: MyBatis 快速掌握 核心概念:理解 My…

8.1 Firmware Update Process

8.1 Firmware Update Process 通过reset激活firmware 更新的过程: host发出firmare下载命令,将FW image下载到控制器。FW image可能有多个部分要下载,因此FW image 下载命令中指定正在下载的FW image的每个部分的偏移量。FW image 下载命令…

Sui创始团队在竞速环节中的快问快答

在Sui Basecamp活动期间,Sui区块链的最初贡献者在Oracle红牛赛车模拟器上展示了他们的技术能力,在驾驶圈时回答了有关Sui的问题。 Evan Cheng(又名Revvin’ Evan)在解释Mysticeti创下区块链最终性记录的同时保持着他的驾驶线路。…

Java | Leetcode Java题解之第200题岛屿数量

题目&#xff1a; 题解&#xff1a; class Solution {void dfs(char[][] grid, int r, int c) {int nr grid.length;int nc grid[0].length;if (r < 0 || c < 0 || r > nr || c > nc || grid[r][c] 0) {return;}grid[r][c] 0;dfs(grid, r - 1, c);dfs(grid, r…

go Channel原理 (三)

Channel 设计原理 不要通过共享内存的方式进行通信&#xff0c;而是应该通过通信的方式共享内存。 在主流编程语言中&#xff0c;多个线程传递数据的方式一般都是共享内存。 Go 可以使用共享内存加互斥锁进行通信&#xff0c;同时也提供了一种不同的并发模型&#xff0c;即通…

【嵌入式——FreeRTOS】任务

【嵌入式——FreeRTOS】任务 任务创建和删除动态方式创建任务静态方式创建任务 删除任务任务切换调度器任务切换流程 任务挂起任务恢复相关API函数 任务创建和删除 动态方式创建任务 任务的任务控制块以及任务的栈空间所需的内存&#xff0c;均由freeRTOS从freeRTOS管理的堆中…

c#asp.net中字典的使用

字典是一个键值对&#xff0c;可以用来保存数据&#xff0c;再查询&#xff1b; 下面是一个案例&#xff1a;依据多个学号查询多个学生的姓名&#xff0c;只能到数据库查询一次数据&#xff01;&#xff01;&#xff01; 先在数据库查询学号对应的学生&#xff0c;把数据保存在…