th:text为null报错_为vue3.0的学习TS解读高级类型

知识点摘要

本节课主要关键词为: 自动类型推断 / 类型断言 / 类型别名(type) / 映射类型(Pick/Record等...) / 条件类型(extends) / 类型推断(infer)

自动类型推断(不用你标类型了,ts自己猜)

 大家现在写ts的时候一定会在每个变量后面都加上类型吧? 但是?

现在告诉大家有些情况下你不需要标注类型, ts可以根据你写的代码来自动推断出类型:

赋值字面量给变量

let n = 1; // ts会自动推断出n是number类型
n+=3 // 不报错,因为已知类型

let arr1 = []; // 类型为: any[]
arr1.push(1,2,{o:3});

let arr = [1]; // 内部要有数字, 才能推断出正确类型
arr.push(2);

自动阅读if条件判断
let n: number|null = 0.5 < Math.random() ? 1:null;
if(null !== n){
n+=3 // ts知道现在n不是null是number
}
浏览器自带api
document.ontouchstart = ev=>{ // 能自动推断出ev为TouchEvent
console.log(ev.touches); // 不报错, TouchEvent上有touches属性
}
typeof

typeof就是js中的typeof, ts会根据你代码中出现的typeof来自动推断类型:

let n:number|string = 0.5 < Math.random()? 1:'1';

// 如果没有typeof, n*=2会报错, 提示没法推断出当前是number类型, 不能进行乘法运算
if('number' === typeof n) {
n*= 2;
} else {
n= '2';
}

注意: 在ts文档中, 该部分的知识点叫做typeof类型保护, 和其他类型推断的内容是分开的, 被写在高级类型/类型保护章节中.

instanceof

ts会根据你代码中出现的instanceof来自动推断类型:

let obj = 0.5 < Math.random() ? new String(1) : new Array(1);
if(obj instanceof String){
// obj推断为String类型
obj+= '123'
} else {
// obj为any[]类型
obj.push(123);
}

注意: 在ts文档中, 该部分的知识点叫做instanceof类型保护, 和其他类型推断的内容是分开的, 被写在高级类型/类型保护章节中.

类型断言(你告诉ts是什么类型, 他都信)

有些情况下系统没办法自动推断出正确的类型, 就需要我们标记下, 断言有2种语法, 一种是通过"<>", 一种通过"as", 举例说明:

let obj = 0.5 < Math.random() ? 1 : [1]; // number|number[]

// 断言, 告诉ts, obj为数组
(<number[]>obj).push(1);

//等价
(obj as number[]).push(1);

类型别名(type)

类型别名可以表示很多接口表示不了的类型, 比如字面量类型(常用来校验取值范围):

type A = 'top'|'right'|'bottom'|'left'; // 表示值可能是其中的任意一个
type B = 1|2|3;
type C = '红'|'绿'|'黄';
type D = 150;

let a:A = 'none'; // 错误, A类型中没有'none'
更多组合:
interface A1{
a:number;
}
type B = A1 | {b:string};
type C = A1 & {b:string};

// 与泛型组合
type D<T> = A1 | T[];

索引类型(keyof)

js中的Object.keys大家肯定都用过, 获取对象的键值, ts中的keyof和他类似, 可以用来获取对象类型的键值:

type A = keyof {a:1,b:'123'} // 'a'|'b'
type B = keyof [1,2] // '1'|'2'|'push'... , 获取到内容的同时, 还得到了Array原型上的方法和属性(实战中暂时没遇到这种需求, 了解即可)

可以获得键值, 也可以获取对象类型的值的类型:

type C = A['a'] // 等于type C = 1;
let c:C = 2 // 错误, 值只能是1

映射类型(Readonly, Pick, Record等...)

映射类型比较像修改类型的工具函数, 比如Readonly可以把每个属性都变成只读:

type A  = {a:number, b:string}
type A1 = Readonly<A> // {readonly a: number;readonly b: string;}

打开node_modules/typescript/lib文件夹可以找到lib.es5.d.ts, 在这我们能找到Readonly的定义:

type Readonly<T> = {
readonly [P in keyof T]: T[P];
};

其实不是很复杂, 看了本节课前面前面的内容, 这个很好理解是吧:

  1. 定义一个支持泛型的类型别名, 传入类型参数T.

  2. 通过keyof获取T上的键值集合.

  3. in表示循环keyof获取的键值.

  4. 添加readonly标记.

Partial, 让属性都变成可选的
type A  = {a:number, b:string}
type A1 = Partial<A> // { a?: number; b?: string;}
Required, 让属性都变成必选
type A  = {a?:number, b?:string}
type A1 = Required<A> // { a: number; b: string;}
Pick, 只保留自己选择的属性, U代表属性集合
type A  = {a:number, b:string}
type A1 = Pick<A, 'a'> // {a:number}
Omit 实现排除已选的属性
type A  = {a:number, b:string}
type A1 = Omit<A, 'a'> // {b:string}
Record, 创建一个类型,T代表键值的类型, U代表值的类型
type A1 = Record<string, string> // 等价{[k:string]:string}
Exclude, 过滤T中和U相同(或兼容)的类型
type A  = {a:number, b:string}
type A1 = Exclude<number|string, string|number[]> // number

// 兼容
type A2 = Exclude<number|string, any|number[]> // never , 因为any兼容number, 所以number被过滤掉
Extract, 提取T中和U相同(或兼容)的类型
type A  = {a:number, b:string}
type A1 = Extract<number|string, string|number[]> // string
NonNullable, 剔除T中的undefined和null
type A1 = NonNullable<number|string|null|undefined> // number|string
ReturnType, 获取T的返回值的类型
type A1= ReturnType<()=>number> // number
InstanceType, 返回T的实例类型

ts中类有2种类型, 静态部分的类型和实例的类型, 所以T如果是构造函数类型, 那么InstanceType可以返回他的实例类型:

interface A{
a:HTMLElement;
}

interface AConstructor{
new():A;
}

function create (AClass:AConstructor):InstanceType<AConstructor>{
return new AClass();
}
Parameters 获取函数参数类型

返回类型为元祖, 元素顺序同参数顺序.

interface A{
(a:number, b:string):string[];
}

type A1 = Parameters<A> // [number, string]
ConstructorParameters 获取构造函数的参数类型

Parameters类似, 只是T这里是构造函数类型.

interface AConstructor{
new(a:number):string[];
}

type A1 = ConstructorParameters<AConstructor> // [number]

extends(条件类型)

T extends U ? X : Y

用来表示类型是不确定的, 如果U的类型可以表示T, 那么返回X, 否则Y. 举几个例子:

type A =  string extends '123' ? string :'123' // '123'
type B = '123' extends string ? string :123 // string

明显string的范围更大, '123'可以被string表示, 反之不可.

infer(类型推断)

单词本身的意思是"推断", 实际表示在extends条件语句中声明待推断的类型变量. 我们上面介绍的映射类型中就有很多都是ts在lib.d.ts中实现的, 比如Parameters:

type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;

上面声明一个P用来表示...args可能的类型, 如果(...args: infer P)可以表示 T, 那么返回...args对应的类型, 也就是函数的参数类型, 反之返回never.

注意: 开始的T extends (...args: any) => any用来校验输入的T是否是函数, 如果不是ts会报错, 如果直接替换成T不会有报错, 会一直返回never.

应用infer

接下来我们利用infer来实现"删除元祖类型中第一个元素", 这常用于简化函数参数

export type Tail<Tuple extends any[]> = ((...args: Tuple) => void) extends ((a: any, ...args: infer T) => void) ? T : never

---END---

选择”Vue社区 “星标?,内容一触即达。点击原文更多惊喜!

开发者技术前线 汇集技术前线快讯和关注行业趋势,大厂干货,是开发者经历和成长的优秀指南。

历史推荐

7个有用的Vue开发技巧

JavaScript八张思维导图

JavaScript 之实现一个简单的 Vue

080452923335ebfcb41e934e8c1a6e44.png

听说有人不敢点这里 ?

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

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

相关文章

Hive与Hadoop的调用关系

一、调用图 二、步骤解析 1、提交sql 交给驱动 2、驱动编译&#xff1a;解析相关的字段表信息 3、去metastore查询相关的信息 返回字段表信息 4、编译返回信息 发给驱动 5、驱动发送一个执行计划 交给执行引擎 6、执行计划 6.1、DDLs 对数据库表的操作的 直接和metastore交互 …

简述计算机文件的命名办法,如何进行文件命名-如何进行文件管理

如何进行文件命名-如何进行文件管理电脑的管理事实上就是文件和文件夹的管理。想要我们的电脑干净整齐&#xff0c;就需要我们正确的进行文件管理。我们知道了文件和文件夹的概念之后&#xff0c;现在我们再来看看单独的文件&#xff0c;认识一下文件的构成以及文件命名和命名规…

网页加载出现没有合适的负载均衡器_分布式必知必会-七层负载和四层负载到底是什么?...

背景我们在使用负载均衡器的时候&#xff0c;往往会听到七层负载或四层负载这两个名词&#xff0c;许多负载均衡软件提供的方式也不同&#xff0c;那么七层和四层区别在哪呢&#xff1f;为什么有的支持有的不支持呢&#xff1f;负载均衡简介负载均衡建立在现有网络结构之上&…

博弈论 斯坦福game theory stanford week 3.2_

title: 博弈论 斯坦福game theory stanford week 3-1 tags: note notebook: 6- 英文课程-15-game theory --- 博弈论 斯坦福game theory stanford week 3-1 习题 第 1 个问题 We say that a game is dominance solvable, if iterative deletion of strictly dominated strategi…

nestjs swagger文档调用需要鉴权的接口

目标 nestjs经常需要设置一些鉴权&#xff08;登录后&#xff09;才能访问的接口&#xff0c;但是生成的swagger文档可以发起接口请求&#xff0c;文档发起的请求默认是不携带登录token的&#xff0c;所以需要移除swagger文档发起请求的守卫拦截。 nestjs守卫拦截设置见另一篇…

ajax预加载html seo,前端性能优化 — JS预加载和懒加载

JS预加载需求&#xff1a;有时我们需要实现例如快速快速切换页面、图片之类的功能时&#xff0c;能尽快的加载出我们所需的图片会极大提升用户体验&#xff0c;这时用预加载将图片先缓存到浏览器&#xff0c;用户使用需显示图片时无疑会顺畅很多。核心&#xff1a;当一个图片在…

和平精英显示服务器人数太多,和平精英到底有多差 导致玩家纷纷国际服

原标题&#xff1a;和平精英到底有多差 导致玩家纷纷国际服和平精英上线以来争议不断&#xff0c;百分之九十九是对和平精英的各种不满&#xff0c;还有百分之一是喜欢和平精英&#xff0c;认为刺激战场已经免费给我们玩&#xff0c;让腾讯亏了很多钱&#xff0c;现在和平精英上…

python中的wx_配置 Python的wxWidgets可视开发环境 | 学步园

注&#xff1a;转载请注明出处 一、下载 Python 2.5.1 这一步是必须做的&#xff0c;下载 Python 语言的 SDK 下载地址(直接复制到迅雷)&#xff1a;点击下载 下载完成后安装 Python 2.5.1&#xff0c;注意安装路径中不要有空格&#xff0c;不然会引起一些问题。 二、下载 wxPy…

的write方法有哪些参数_向子进程传递大量数据的方法

如何传递大型数据给子进程昨天的一篇文章中&#xff0c;我们说到如果想向一个子进程传输多于32767个字符的数据&#xff0c;我们需要寻找其他的方法(而不是命令行参数)来实现。我们能想到的第一个方法是&#xff1a;WM_COPYDATA。当子进程创建并进入消息循环后&#xff0c;我们…

厉害了!中关村软件园人工智能军团有料有看点

人工智能已成为当下全球科技界的新热点&#xff0c;中外竞相攀登这座划时代的科技高峰。上月&#xff0c;国务院印发《新一代人工智能发展规划》&#xff0c;明确将人工智能作为未来国家重要的发展战略。《规划》提出前瞻布局新一代人工智能重大科技项目&#xff0c;到2030年中…

Hive的使用之hwi

概述 hwi是hive开发的网页形式查看数据。方便非专业人士使用。 安装步骤 1、下载hive源码包 地址&#xff1a;http://apache.fayea.com/hive/ apache-hive-2.1.0-src.tar.gz 2、打包war 解压apache-hive-2.1.0-src.tar.gz源码包&#xff0c;进入到 C:\Users\zengmg\Deskto…

c 服务器传输大文件,cend.me:不须经过服务器,直接点对点的文件传输免费服务...

要传送文件给远程的手机、平板、电脑等设备&#xff0c;通常的做法就是先将文件上传到服务器存放&#xff0c;然后再从服务器下载&#xff0c;这样的做法看似合理&#xff0c;但如果上传的同时就由远程的设备来接收&#xff0c;不要经过服务器&#xff0c;这样就能更节省上、下…

Thrift源码学习二——Server层

Thrift 提供了如图五种模式&#xff1a;TSimpleServer、TNonblockingServer、THsHaServer、TThreadPoolServer、TThreadSelectorServer ​​ TSimpleServer、TThreadPoolServer 属于阻塞模型 TNonblockingServer、THsHaServer、TThreadedSelectorServer 属于非阻塞模型 TServer…

base64是哪个jar包的_涨知识 | 用maven轻松管理jar包

前言相信只要做过 Java 开发的童鞋们&#xff0c;对 Ant 想必都不陌生&#xff0c;我们往往使用 Ant 来构建项目&#xff0c;尤其是涉及到特别繁杂的工作量&#xff0c;一个 build.xml 能够完成编译、测试、打包、部署等很多任务&#xff0c;这在很大的程度上解放了程序员们的双…

JMS(Java消息服务)与消息队列ActiveMQ基本使用(一)

最近的项目中用到了mq&#xff0c;之前自己一直在码农一样的照葫芦画瓢。最近几天研究了下&#xff0c;把自己所有看下来的文档和了解总结一下。 一. 认识JMS 1.概述 对于JMS,百度百科&#xff0c;是这样介绍的&#xff1a;JMS即Java消息服务&#xff08;Java Message Service&…

hive复合数据类型之struct

概述 STRUCT&#xff1a;STRUCT可以包含不同数据类型的元素。这些元素可以通过”点语法”的方式来得到所需要的元素&#xff0c;比如user是一个STRUCT类型&#xff0c;那么可以通过user.address得到这个用户的地址。 操作实例 1、创建表 create table student_test(id int,in…

hive复合数据类型之array

概述 ARRAY&#xff1a;ARRAY类型是由一系列相同数据类型的元素组成&#xff0c;这些元素可以通过下标来访问。比如有一个ARRAY类型的变量fruits&#xff0c;它是由[apple,orange,mango]组成&#xff0c;那么我们可以通过fruits[1]来访问元素orange&#xff0c;因为ARRAY类型的…

hive复合数据类型之map

概述 MAP&#xff1a;MAP包含key->value键值对&#xff0c;可以通过key来访问元素。比如”userlist”是一个map类型&#xff0c;其中username是key&#xff0c;password是value&#xff1b;那么我们可以通过userlist[username]来得到这个用户对应的password&#xff1b; 操…

Beego框架使用

为什么80%的码农都做不了架构师&#xff1f;>>> Beego Web项目目录结构 new 命令是新建一个 Web 项目&#xff0c;我们在命令行下执行 bee new <项目名> 就可以创建一个新的项目。但是注意该命令必须在 $GOPATH/src 下执行。最后会在 $GOPATH/src 相应目录下…

oracle下lag和lead分析函数

Lag和Lead分析函数可以在同一次查询中取出同一字段的前N行的数据(Lag)和后N行的数据(Lead)作为独立的列。 这种操作可以代替表的自联接&#xff0c;并且LAG和LEAD有更高的效率。 语法&#xff1a; [sql] view plaincopy /*语法*/ lag(exp_str,offset,defval) over() Lead(…