typescript学习回顾(三)

今天继续来分享ts的相关概念,枚举,ts模块化,接口和类型兼容性

ts的扩展类型:类型别名,枚举,接口和类

枚举

基础概念

枚举通常用于约束某个变量的取值范围。当然字面量和联合类型配合使用,也可以达到同样的目标。

为什么使用枚举

但是使用字面量和联合联系会存在一个问题

  • 逻辑含义和真实值容易混淆,修改真实值的时候,会产生大量的修改
  • 字面量类型不会进入编译结果

使用枚举的话就不会出现这种问题

如何定义枚举
/*
enum 枚举名{
    枚举字段1 = 值1,
    枚举字段2 = 值2,
    ..
}
*/

//实例
 enum Gender {
     Male = "帅哥",
    Female = "美女"
 }

// 先生 女士  男 女 male  female
 let 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,   //0001
    Write = 2,  //0010
    Create = 4, //0100
    Delete = 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: string
    age: number
    sayHello: () => 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:

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

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

结语

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

电脑开机之后屏幕没有任何显示?怎么检查?

前言 最近有很多小伙伴来咨询,自己的电脑开机之后,屏幕真的是一点显示都没有,只有CPU风扇在转。 这个情况小白经常经常经常遇到,所以写一篇关于这个问题的排查教程。按照这个教程来排查,除非真的是硬件损坏&#xff…

武汉星起航:挂牌上海股权交易中心,自营店铺销售额迎飞跃式增长

2023年10月30日,对于武汉星起航电子商务有限公司而言,无疑是一个载入史册的重要日子。这一天,公司成功在上海股权托管交易中心挂牌展示,正式登陆资本市场,开启了全新的发展篇章。这一里程碑式的跨越,不仅彰…

从写下第1个脚本到年薪40W,我的测试开发心路历程!

对于任何职业来说,薪资始终都会是众多追求的重要部分。前几年测试行业还是风口,但是随着不断新鲜血液的加入,再加上就业大环境不好,企业也都在“降本增效”。目前内卷也是越来越激烈。不得不承认当下的现状,已经不仅仅…

构建家庭NAS之二:TrueNAS Scale规划、安装与配置

本系列文章索引: 构建家庭NAS之一:用途和软硬件选型 构建家庭NAS之二:TrueNAS Scale规划、安装与配置 构建家庭NAS之三:在TrueNAS SCALE上安装qBittorrent 首先声明一下,我用的版本是TrueNAS SCALE 24.04.1.1&#xf…

打印一张A4纸多少钱?打印a4多少钱一张

在数字化日益发展的今天,打印服务依然是办公、学习和生活中不可或缺的一部分。对于广大用户来说,了解A4纸打印的价格成为选择打印服务的重要参考因素。那么,A4纸打印到底多少钱一张呢? 在琢贝云打印平台,打印价格非常实…

基于Java技术的在线学习平台系统

开头语:你好呀,我是计算机学姐码农小野!如果有相关需求,可以私信联系我。 开发语言:Java 数据库:MySQL 技术:Java技术,基于SpringBoot框架 工具:Eclipse、Navicat、M…

《计算机英语》 Unit 6 Internet 互联网

Section A Internet 互联网 The Internet is a global system of interconnected computer networks that use the standard Internet protocol suite (TCP/IP) to link several billion devices worldwide. 互联网是一个全球性的互连计算机网络系统,使用标准的互联…

cuda与cudnn下载(tensorflow-gpu)

目录 前言 正文 前言 !!!tensorflow-gpu的版本要与cuda与cudnn想对应。这点十分重要!推荐下载较新的。即tensorflow-gpu2.60及以上,cuda11.x及以上,cudnn8.x及以上。 所以,下载之前先检查好…

海外代理IP哪个可靠?如何测试代理的稳定性?

在数字化时代,互联网已成为我们日常生活的重要组成部分。然而,随着网络活动的增加,我们面临的安全威胁也随之增加。 黑客攻击、数据泄露、网络钓鱼等安全事件频发,严重威胁着我们的个人隐私和网络安全。代理服务器在当今的互联网世…

树莓派4B_OpenCv学习笔记13:OpenCv颜色追踪_程序手动调试HSV色彩空间_检测圆

今日继续学习树莓派4B 4G:(Raspberry Pi,简称RPi或RasPi) 本人所用树莓派4B 装载的系统与版本如下: 版本可用命令 (lsb_release -a) 查询: Opencv 版本是4.5.1: OpenCv颜色追踪_程序手动调试HSV色彩空间_检测灰度图中的…

绕过命令过滤器:探索UnixLinux中的Bypass技术

前言 在Unix或Linux系统的安全测试和网络防御中,了解如何绕过命令过滤器是非常重要的。今天,我们将探讨几种利用shell命令绕过安全限制的技巧,这些技巧常用于渗透测试中,以检测系统的安全漏洞。 0x00 命令介绍 一般而言&#x…

web前端——VUE

1.什么是框架? ①概述 框架结构就是基本功能,把很多基础功能已经实现了、封装了。在基础语言之上,对各种基础功能进行封装,方便开发者,提高开发效率 ②前端框架 javaScript是原生的 vue.js: 是一个js框架&…

一文了解Linux中的内存映射

目录 一、概念 工作原理: 特点: 适用场景: 二、详解mmap()函数 1. mmap的基本概念 2. mmap的特点 3. mmap的用途 4. mmap的优缺点 三、实验 实验一:基础读写实验 实验二:证明开始显…

three.js基础环境搭建

three.js three.js介绍安装threejs文件资源目录介绍本地静态服务器vscode配置live-server插件nodejs配置本地静态服务器项目的开发环境引入threejs 基础知识右手坐标系程序结构 three.js介绍 three.js官网 Three.js是一款基于WebGL的JavaScript 3D库,它使得开发者能…

Spring统一功能

文章目录 一、什么是统一功能二、拦截器2.1 什么是拦截器2.2 拦截器的使用2.3 案例:不拦截前端的请求2.4 拦截器是如何实现的 ---- >分析DispatcherServlet源码分析 三、适配器模式四、统一数据返回格式五、统一异常六、案例:在图书管理系统使用统一功…

Linux系统启动流程

init程序类型: ①、SysV:init,centos 5之前,配置文件/etc/init.d/ ②、Upstart: init,centos 6,配置文件/etc/init.d/ /etc/init/ ③、Systemd:Systemd,centos 7,配置文件/usr/li…

鸿蒙开发系统基础能力:【@ohos.systemTime (设置系统时间)】

设置系统时间 本模块用来设置、获取当前系统时间,设置、获取当前系统日期和设置、获取当前系统时区。 说明: 本模块首批接口从API version 7开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。 导入模块 import systemTime …

第三十三篇——互联网广告:为什么Google搜索的广告效果好?

目录 一、背景介绍二、思路&方案三、过程1.思维导图2.文章中经典的句子理解3.学习之后对于投资市场的理解4.通过这篇文章结合我知道的东西我能想到什么? 四、总结五、升华 一、背景介绍 对于信息的利用,再广告这个维度中去洞察,你又能发…

在低版本Excel中创建次级下拉列表

在低版本中indirect函数不支持选区,创建次级下拉列表得依靠“名称管理”给选区命名。 (笔记模板由python脚本于2024年06月26日 06:24:22创建,本篇笔记适合常用Excel处理数据的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网:https://www…

3.任务的创建与删除

1.什么是任务? 任务可以理解为进程/线程,创建一个任务,就会在内存开辟一个空间。 任务通常都含有while(1)死循环 2.任务创建与删除相关的函数 3.CUBEMAX相关配置 编辑一个led1闪烁的任务