typescript 进阶(一)

news/2024/7/7 21:16:56/文章来源:https://www.cnblogs.com/Grewer/p/18282448

前言

本文主要记录个人在使用 typescript 时的一些用法,介绍 typescript 。建议在阅读前先了解 typescript 的基础语法。

互斥键的类型

在 ts 官网的联合类型文档中有这样一种情况:

type Shape =| { kind: "circle"; radius: number }| { kind: "square"; x: number }| { kind: "triangle"; x: number; y: number };function area(s: Shape) {if (s.kind === "circle") {return Math.PI * s.radius * s.radius;} else if (s.kind === "square") {return s.x * s.x;} else {return (s.x * s.y) / 2;}
}

在此种情况下 ts 可以正常判断这两种类型的联合, 但是我们这样判断:

function area(s: Shape) {if (s.radius) { // if 中判断修改return Math.PI * s.radius * s.radius;} else if (s.kind === "square") {return s.x * s.x;} else {return (s.x * s.y) / 2;}
}

点此在线查看

或者是这样, 没有 type 的情况:

type Shape =| { radius: number, cal: ()=>number}| { x: number }function area(s: Shape) {if(s.cal){return s.cal()}else{return s.x * s.x;}
}

点此在线查看

这里就会报如下的错误:

Property 'cal' does not exist on type 'Shape'.Property 'cal' does not exist on type '{ x: number; }'.

ts 在联合类型中, 我们直接通过 . 获取的属性, 是必须在所有子类型中共有的

这里我们有 2 种结局方案

  1. 使用 in 操作符
type Shape =| { radius: number, cal: ()=>number}| { x: number }function area(s: Shape) {if ('cal' in s) {return s.cal()} else {return s.x * s.x;}
}

点此在线查看

  1. 使用特殊的类型库来包装

函数类型

有时候函数我们也会当做对象来使用:

interface IFN {(): number;name: string
}const a: IFN = () => {//...return 1
}a.name = 'test'

同样地, 会有一些特殊的函数, 如 Date, 他有多套不同的函数:

new Date(1656953943886)
// Tue Jul 05 2022 00:59:03 GMT+0800 (中国标准时间)
// Date 对象new Date('2022-12-1')
// Thu Dec 01 2022 00:00:00 GMT+0800 (中国标准时间)
// 也是 Date 对象// ...

在 ts 的声明中他是这样被描述的

interface DateConstructor {new(): Date;new(value: number | string): Date;new(year: number, month: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number): Date;(): string;readonly prototype: Date;parse(s: string): number;UTC(year: number, month: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number): number;now(): number;
}

字面量类型

// @errors: 2345
declare function handleRequest(url: string, method: "GET" | "POST"): void;
// ---cut---
const req = { url: "https://example.com", method: "GET" };
handleRequest(req.url, req.method);

点此在线查看

解决方案

  1. 使用泛型:
// Change 1:
const req = { url: "https://example.com", method: "GET" as "GET" };
// Change 2
handleRequest(req.url, req.method as "GET");
  1. as const
const req = { url: "https://example.com", method: "GET" } as const;
handleRequest(req.url, req.method);

此例子在官网文档中也有提到: https://www.typescriptlang.org/docs/handbook/2/everyday-types.html

对象

重新映射

通过对象 as 重新映射出类型:

type Getters<Type> = {[Property in keyof Type as `get${Capitalize<string & Property>}`]: () => Type[Property]
};interface Person {name: string;age: number;location: string;
}type LazyPerson = Getters<Person>;// type LazyPerson = {
//  getName: () => string;
//  getAge: () => number;
//  getLocation: () => string;
// }

点此在线查看

映射中添加条件判断:

type ExtractPII<Type> = {[Property in keyof Type]: Type[Property] extends { pii: true } ? true : false;
};type DBFields = {id: { format: "incrementing" };name: { type: string; pii: true };
};type ObjectsNeedingGDPRDeletion = ExtractPII<DBFields>;// type ObjectsNeedingGDPRDeletion = {
//     id: false;
//     name: true;
// }

点此在线查看

枚举

静态枚举

const enum ITypeEnums {Input ,Select
}// 普通枚举:enum ITypeEnums {Input ,Select
}

经过编译后:

var ITypeEnums2;
(function (ITypeEnums2) {ITypeEnums2[ITypeEnums2["Input"] = 0] = "Input";ITypeEnums2[ITypeEnums2["Select"] = 1] = "Select";
})(ITypeEnums2 || (ITypeEnums2 = {}));

很明显的是静态枚举消失了

这是 ts 为了避免在访问枚举值时额外的生成代码的代价

静态枚举的编译

const enum ITypeEnums {Input ,Select
}let types = [ITypeEnums.Input,ITypeEnums.Select
];const type: ITypeEnums.Input = 1
let types = [0 /* ITypeEnums.Input */,1 /* ITypeEnums.Select */
];
const type = 1;

枚举的选择

什么情况下选择枚举, 而什么情况下会选择对象

在一般情况下, 我们使用静态对象就够了:

const enum EDirection {Up,Down,Left,Right,
}const ODirection = {Up: 0,Down: 1,Left: 2,Right: 3,
} as constlet a = ODirection.Up
// 提示 Up: 0

对状态进行多种判断时, 我们用到枚举的情况会更多(尤其是静态枚举)


const enum EDirection {Up,Down,Left,Right,
}const getStatus = (status: EDirection) => {switch(status){case EDirection.Up:return 'success'case EDirection.Down:return 'fail'default:return null}
}

编译之后的结果:

const getStatus = (status) => {switch (status) {case 0 /* EDirection.Up */:return 'success';case 1 /* EDirection.Down */:return 'fail';default:return null;}
};

点击在线查看

比较下非静态枚举的编译:

var EDirection;
(function (EDirection) {EDirection[EDirection["Up"] = 0] = "Up";EDirection[EDirection["Down"] = 1] = "Down";EDirection[EDirection["Left"] = 2] = "Left";EDirection[EDirection["Right"] = 3] = "Right";
})(EDirection || (EDirection = {}));
const getStatus = (status) => {switch (status) {case EDirection.Up:return 'success';case EDirection.Down:return 'fail';default:return null;}
};

通过此种静态枚举的方案来判断类型, 比较 Object['name'] 的方式和普通枚举的方式来说,
性能更好, 可维护性也更高

有静态方法的枚举

你可以使用 enum + namespace 的声明的方式向枚举类型添加静态方法。

这里的枚举只支持普通枚举


enum EDirection {Up,Down,Left,Right,
}namespace EDirection {export function go(type: EDirection) {switch (type) {case EDirection.Up:case EDirection.Down:return false;default:return true;}}
}EDirection.go(EDirection.Down)

搭配使用可以在状态的基础上, 作出各种变化和判断方法

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

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

相关文章

VMware安装CentOS7环境

准备 CentOS7的iso镜像 下载链接:https://mirrors.aliyun.com/centos/7/isos/x86_64/配置步骤 步骤一——创建虚拟机 1、点击创建新的虚拟机2、选择典型3、选择镜像文件4、填写对应信息5、选择虚拟机存储的位置6、存储为单个文件7、创建步骤二——配置centos7 1、打开虚拟机后…

Mybatis执行器

mybatis执行sql语句的操作是由执行器(Executor)完成的,mybatis中一共提供了3种Executor:类型 名称 功能REUSE 重用执行器 缓存PreparedStatement,下一次执行相同的sql可重用BATCH 批量执行器 将修改操作记录在本地,等待程序触发或有下一次查询时才批量执行修改操作SIMPLE…

本地安装seata

1. 下载,解压steata安装包 2. 修改配置里面的端口号 只要是localhost或者不是自己的端口号都更改成自己的端口号3. 修改配置nacos的文件执行 4、数据库中添加对应的表 数据库中的表名称尽量位seata_server,避免后面去修改 5、线上nacos配置 在public 下面进行配置,修改自己对…

关于自定义unordered_set\unordered_map中Hash和KeyEqual:函数对象和lambda表达式简单应用

以unordered_set为例,首先在cppreference中查看其模板定义:可以看到Hash类默认是std::hash<Key,KeyEqual类似,本文将Hash以函数对象写出,将KeyEqual以lambda写出。 class hashvec{public:size_t operator()(const vector<int> & vec) const {return hash<…

Python预测体重变化:决策树、tf神经网络、随机森林、梯度提升树、线性回归可视化分析吸烟与健康调查数据

全文链接:https://tecdat.cn/?p=36648 原文出处:拓端数据部落公众号 在当今的数据驱动时代,机器学习算法已成为解析复杂数据集、揭示隐藏模式及预测未来趋势的重要工具。特别是在医疗健康领域,这些算法的应用极大地提升了我们对疾病预防、诊断及治疗方案的理解与制定能力。…

Nuxt3 的生命周期和钩子函数(九)

摘要:本文介绍了Nuxt3中与Vite相关的五个生命周期钩子,包括vite:extend、vite:extendConfig、vite:configResolved、vite:serverCreated和vite:compiled,展示了如何在每个钩子中扩展Vite配置、读取配置、添加中间件和处理编译事件。每个钩子都有详细的描述和示例代码,帮助开…

地理信息科学:生态保护的智慧经纬

在地球这颗蓝色星球上,每一片森林的呼吸、每一条河流的流淌,都是生命交响曲中不可或缺的音符。而地理信息科学(GIS),正是我们手中解读自然密码、护航生态平衡的精密仪器。今天,让我们深入探讨GIS如何在生物多样性保护和生态系统管理中发挥其不可替代的作用。 🌱 GIS——…

软连接与硬链接

(1)软链接(symbolic link) 创建命令:ln -s <target> <link_name>其中:<target> 是目标文件或目录的路径,可以是相对路径或绝对路径。<link_name> 是要创建的软链接的名称,可以是相对路径或绝对路径。特点:笔试面试填空题和简答题:软链接的特点…

pycharm导入第三方包出现红色波浪线或新建flask项目出现红色波浪线解决办法

设置 -> 项目结构(Project Structure) ,将site-packages设为源代码

开源软件开发平台哪家好?

低代码技术平台、开源软件开发平台哪家好?进行数字化转型,离不开低代码技术平台等软件产品的加持与助力。因为它更好操作、更灵活、易维护等优势特点突出,在推动企业实现流程化办公的过程中助力明显,作用大,深得客户喜爱。那么,低代码技术平台、开源软件开发平台哪家好?…

阿里云 SAE 助力修正商城 3 周内提升系统承载能力 20 倍,轻松应对春晚流量

修正技术团队迫切需要升级 APP 架构以应对即将到来的超高并发场景。这一挑战不仅是对技术的考验,更是对修正品牌实力的一次展示。为了应对这次巨大的技术挑战,修正技术团队选择与阿里云云原生团队合作,进行 APP 架构的升级。作者:赵世振、刘松伟、朱坪" 从了解阿里云 …

使用yum 命令安装 dotnet 6

如果是超级管理员账号root 登录 不需要加 sudo。 sudo rpm -Uvh https://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpmsudo yum install dotnet-sdk-6.0sudo yum install dotnet-runtime-6.0 输入dotnet --info 查看 安装的 dotnet 版本

SpringCloud Alibaba Nacos 配置动态更新源码学习总结

众所周知,nacos两大核心功能,服务注册发现与动态配置 支持服务注册发现的有:Eureka、Consul、Zookeeper、Nacos 支持动态配置的有:Spring Cloud Config、Nacos、Apollo、Consul 像支持分布式的框架,必须得借用第三方服务,比如定时任务调度xxl-job,分布式事务seata,都分为…

实战篇——SQL注入sqli-labs-master靶场实战三

实战篇——SQL注入sqli-labs-master靶场实战(3) sqlmap基础用法 GET型:POST型:请求头注入(以User-Agent注入为例):爆库: python sqlmap.py -r C:\Users\yaogu\Desktop\sqlmap\request\1.txt --threads 10 --dbs爆表: python sqlmap.py -r C:\Users\yaogu\Desktop\sqlmap\r…

xshell终端显示乱码的处理方法

File -> Properties -> 终端, 编码切换为GBK2312 参考:https://www.cnblogs.com/my-first-blog-lgz/p/17337055.html

web前端应用性能指标测量工具有哪些?

接上一篇介绍前端性能指标的内容,本文主要总结下一般使用的性能测量工具。 1、可以借助 Gooogle 开源的 web-vitals 库来测量一些性能指标: import {onCLS, onINP, onLCP, onFCP, onFID, onTTFB} from web-vitals; onCLS(console.log); onINP(console.log); onLCP(console.lo…

web前端应用应该关注哪些性能指标?

作为一个有经验的前端开发工程师来说,关注性能是必不可少的一项日常工作,那么应该重点关注一些什么样的性能指标呢?其实主要还是从用户体验的角度来看,一般我们会从页面加载相关、交互相关方面入手。 原文:前端性能指标,一网打尽FCP:首次内容绘制 LCP:最大内容绘制 TTF…

解决Centos无法yum源的问题

1、安装yum依赖包,出现报错could not resolve host :mirrorlist.centos.org:unknown error 此时 #ping mirrors.aliyun.com 不通 一般是由于dns解析存在问题,cd /etc/resolv.conf 修改nameserver 改为114.114.114.114。重启网卡:systemctl restart network 再次 #ping mir…

数据万象盲水印 - AIGC的“保护伞”

近期AIGC的爆火让人们觉得AI似乎无所不能,打工人们已然将 AI 发展成了工作的一大助手,但同样也伴随着很多AI的受害者。一些专家、画家、学者们发现自己的“作品风格”正在被 AI “抄袭剽窃”。导语 近期AIGC的爆火让人们觉得AI似乎无所不能,打工人们已然将 AI 发展成了工作的…