TypeScript值比较、泛型函数类型和签名
TS类型缩小
当形参可以接受多种类型时,就需要对传入数据的类型进行检测
typeof xxx === 'xxx’叫做类型守护,表示判断某个变量是否属于某种类型,而且不用担心类型不符合等错误,TS已经智能的为我们处理好了这些问题
function miniType(str: number|string){if(typeof str === 'number'){console.log(new Array(str))}else if(typeof str === 'string'){console.log(str)}
}
TS真值缩小
真值:即除了0 null undefined 0n 这些假值以外的所有值
真值缩小是为了精确定位传入值的数据类型,如下代码所示,对于传入的strs变量,我们仅仅判断它是一个object是不够的,因为null也是一个object对象,这很明显扰乱我们代码逻辑
此时我们在判定条件前面加上 strs && 即可执行真值缩小,代码逻辑变成:该变量类型为object且同时为真值(非null)才成立
function trueNarrow1(strs: string | string[] | null) {if(strs && typeof strs === 'object'){for(const s of strs){console.log(s)}}
}
TS等值缩小
使用 === 或者 !== 则表示严格的等于或者不等于机制
- 上部分代码因形参都具有string类型,那么使用===表示当且仅当俩变量类型都是string的才执行代码
- 下部分代码表示当他不等于null时才执行(特别注意他只针对null这个空值进行判断,因为它是严格的)
// ===符号
function equalNarrow1(s1: string | undefined, s2: string | number) {if(s1===s2){console.log(s1+s2)}
}// !==符号
function equalNarrow2(s3: number|null){if(s3!==null){// ....}
}
使用!=来表示宽松的不等于机制
所谓宽松的,即指它是否定一类而不是单个类型,譬如null和undefined都属于同一类(无意义字符),所以我们只需要令变量 !=null 就可以包含 !=undefined 等多种状况
// !=宽松机制
function equalNarrow3(s4: string|null|undefined){if(s4!=null){// ...}
}
TS in操作符缩小
顾名思义,以下定义了两个物种,鸟和鱼,它们分别具有各自的移动特性,那么我们在判断条件里面使用in缩小操作符将移动条件限制于仅可以游泳,那么自然就会归类到鱼身上,此时的函数调用就不会出错了
type Fish = { swin: () => void }
type Bird = { fly: () => void }function inNarrow(animal: Fish | Bird) {if('swin' in animal){animal.swin()}else{animal.fly()}
}
TS instanceof操作符缩小
和大多数编程语言一致,instanceof检测前者是不是后者的一个实例,如果是的话返回true
function instanceofNarrow(x: Date|string){if(x instanceof Date){console.log(x.toUTCString())}else{console.log(x.toUpperCase())}
}instanceofNarrow(new Date())
instanceofNarrow("helloworld")
TS分配缩小
分配缩小即变量的类型会取决于变量定义式中的可能出现的类型趋向;
说人话就是(以下方代码中的三元运算符示例)
- 如果random取值小于0.5,那么x被赋值12,此刻x为number类型的
- 如果random取值大于0.5,那么x被赋值too samll,此刻x为string类型的
- 所以根据所有趋向,x类型已经固定在了number和string之间,故不能再次把x赋予其他类型的值!
let x = Math.random() < 0.5 ? 12 : 'too small!!!'x=true // 出错,类型不匹配!!!
TS类型谓词
开始变得复杂起来了= w =,请看下文步骤分解
- 类型谓词定义于函数的返回值里面,格式为 parameter is type ,parameter为形参,而type是我们之前定义好的类型
- 在return语句一行,他表示先缩小para范围,然后判断里面有没有方法swin,如果有的话return true,即返回para is ParameterTest1为真,此时函数返回类型ParameterTest1
- 如果return判断的结果为false,那么返回para is ParameterTest1为假,此时函数返回类型ParameterTest2
type ParameterTest1 = {name: stringswin: () => void
}type ParameterTest2 = {name: stringfly: () => void
}function typeParameter(para: ParameterTest1|ParameterTest2): para is ParameterTest1{return (para as ParameterTest1).swin !== undefined
}
TS联合类型unions
所谓的联合类型就是将两个及以上的类型结合成为一个变量,然后根据这些类型的共同参数来划分该联合类型到底属于那种子类型
常常用到switch分支结构,如下方代码所示,根据kind的不同来定位出是与那个子类型
interface u1{kind:'u1'para1:number
}interface u2{kind:'u2'para2: number
}// 创建联合类型
type unionsType = u1|u2// 根据联合类型中共同属性Kind,使用switch分支结构判断所属于那个接口
function unionsDistinct(u:unionsType){switch(u.kind){case 'u1': return u.para1**2case 'u2': return u.para2**4}
}
TS函数类型表达式
下面是一个函数类型代码的解析
如文中的 fn: (a:string) => void 他是一个函数类型,他作为形参而存在
- fn 表示该函数的名称
- a:string 表示形参以及形参的类型
- => void 表示该函数不返回任何值
// 首先定义一个函数,该函数的形参是一个函数类型
function basicFunc1(fn: (a:string) => void){fn('helloworld')
}// 创建一个符合函数类型的函数
function basicFunc2(s: string){console.log(s)
}// 将函数作为实参传递进去
basicFunc1(basicFunc2)
当然,我们依然可以使用type来定义函数类型,此刻,我们可以将上文的basicFunc1改为以下basicFunc3来书写
type BasicFunc = (a:string) => voidfunction basicFunc3(fn:BasicFunc){fn('nameless')
}
TS调用签名
函数调用签名的格式如下方代码第一部分所示
- description: string 这表示签名,签名可以有多个但最好只保留一个
- (someThing:number) : boolean 表示函数接收number类型形参并且返回boolean值,特别注意这里返回值前面写的是冒号而不是箭头!
在用作形参的函数 descriptionFunc2 内,除了要定义和形参中规定一致格式的函数,还需要对签名做出定义!比如在该函数后面就紧跟着了description的定义
// 创建含调用签名的函数类型表达式
type DescriptionFunc = {description: string(someThing:number) : boolean
}// 中继函数,这里面调用了形参函数中的签名description
function descriptionFunc1(fn:DescriptionFunc){console.log(fn.description+fn(100))
}// 作为形参的函数,函数返回值以及形参一一对应之外,还需要对签名做出额外设置
function descriptionFunc2(num: number){console.log(num)return false
}
descriptionFunc2.description='helloworld'descriptionFunc1(descriptionFunc2)
TS构造签名
定义函数类型的方法和调用签名差不多,只是在函数类型的前面加了个new而已
- 特别注意,返回值类型的String是包装器类型,而形参中的string只是一个基元类型!
- 然后在中继函数中return是需要使用new关键词来构造函数
// 构造签名
type StructFunc = {new (s: string): String
}function structFunc(cstr:StructFunc){return new cstr('helloworld')
}const sFunc = structFunc(String)
TS泛型函数
和许多编程语言一样,TS也有泛型函数,下面代码实现了获取数组第一个元素的泛型函数
- getFirstElement(arr: T[]): T | undefined 一个标准的声明泛型函数的格式,T表示泛型类型,这个字母可以任意取
- 在我们使用泛型函数时,可以不用尖括号声明类型,而是让编译器自己推断
- 如果我们使用尖括号指定了类型后,就只能使用该类型的数据了!
// 声明泛型函数
function getFirstElement<T>(arr: T[]): T | undefined {return arr[0]
}getFirstElement<string>(['hello','hey'])
getFirstElement([1,2,3])
手动实现map数据类型:
// 自己实现map数据类型
function map<Input, Output>(arr: Input[], func: (arg: Input) => Output): Output[] {return arr.map(func)
}const parsed = map(['1', '2', '3'], (n) => parseInt(n))
TS泛型函数限制条件
对泛型类型添加约束条件
- <T extends { length: number }> 使用extends关键字对泛型类型T进行限制,花括号中写的是类型T必须具有的属性,所以这里面的名字不是乱取的!!!
- 类型T现在约束为,必须具有属性length,所以我们不能传入一个number作为实参,因为number类型没有属性length
- string和array类型的数据才具有length属性,所以可以放心使用!
// 带有限制条件的泛型函数
function longestValue<T extends { length: number }>(a: T, b: T) {if (a.length > b.length) {// ...} else if (a.length < b.length) {// ...}
}const lstr = longestValue('hellow', 'world')
const nstr = longestValue(100, 10) // 错误!Number类型没有属性length
指定类型参数
当形参有两个及以上时,我们希望传入不同类型的实参,此时就需要显式指定类型参数,不能让编译器自动推断!!!
显示声明类型的顺序要和传入的实参类型一一配对,且尖括号内声明的类型使用竖线隔开
// 指定泛型函数类型
function setParametersType<T>(arr1: T[], arr2: T[]): T[] {return arr1.concat(arr2)
}// 显示指定形参的泛型类型,注意顺序配对不可以出错
const spt = setParametersType<string | number>(['a', 'b'], [1, 2])
TypeScript值比较、泛型函数类型和签名相关推荐
- Typescript常见三种函数类型
Typescript有常见三种函数类型: 分别是普通的函数: 有可选参数的函数: 有剩余参数的函数: 普通函数 function findMan(age:number):string{return ' ...
- java泛型函数类型推断_为什么javac可以推断用作参数的函数的泛型类型参数?
在下面的示例中,为什么编译器能够推断出在Foo.test()中第一次调用Foo.create()的通用参数,但是在第二个样例中却不能这么做?我正在使用 Java 6. public class Non ...
- c语言函数返回值类型必须,C++中函数类型与定义的函数返回值类型必须相同么?...
C++中函数类型与定义的函数返回值类型必须相同么?以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! C++中函数类型与定义 ...
- Typescript类,泛型,各种类型工具
一.TypeScript 类 一个类可以包含以下几个模块: 1.属性 1.1 类属性 1.2 实例属性 2.构造函数(在python中叫初始化函数) 该函数在类实例化时会被立即调用 3.方法(也是函数 ...
- 【TS】1368- 秒懂 TypeScript 泛型工具类型!
阿宝哥精心准备的<轻松学 TypeScript> 视频教程已经更新到第十九期了,合集播放量已达 14W+.通过形象生动的动画,让你轻松搞懂 TypeScript 的难点和核心知识点! 如果 ...
- typescript (TS)进阶篇 --- 内置高阶泛型工具类型(Utility Type)
第一部分 前置内容 关键字 keyof 索引查询 对应任何类型T,keyof T的结果为该类型上所有公有属性key的联合: interface Eg1 {name: string,readonly a ...
- php 函数返回值mixed,认识函数的类型、参数与返回值
函数的类型.参数与返回值 一.函数的基本语法语法 functionfunctionName(类型限定参数列表):返回值类型 { } 案例:计算两个数之和. functionsum(int$a,int$ ...
- Swift2.0语言教程之函数的返回值与函数类型
Swift2.0语言教程之函数的返回值与函数类型 Swift2.0中函数的返回值 根据是否具有返回值,函数可以分为无返回值函数和有返回值函数.以下将会对这两种函数类型进行讲解. Swift2.0中具有 ...
- 返回值类型与函数类型不匹配_golang基础语法,定义函数类型 为已存在的数据类型起别名...
简介 在 GO 语言中还有另外一种定义使用函数的方式,就是函数类型,所谓的函数类型就是将函数作为一种类型可以用来定义变量,这种用法类似于前面我们讲过的 int ,float64,string 等类型, ...
最新文章
- linux文件编辑操作,Linux下文本编辑及其文件操作
- postman 使用_如何使用Postman实现数据驱动?
- 点击别的地方隐藏下拉列表
- Android Gradle 学习笔记(四):Gradle 构建脚本
- SAP Leonardo机器学习Restful API如何获得Access Token
- npm --- 包的发布与导入
- 聊聊推荐系统中的偏差
- 如何用手机打开dcm格式图片_压缩图片用这个神奇吧(电脑版)
- python基础知识学习笔记(2)
- (89)多周期时序约束(四)
- python编写自动化脚本工具_python自动化工具之pywinauto实例详解
- 日本惊现史上最大数字货币被盗案,加密货币交易所疑遭黑客盗走620亿日元!
- Linux服务器网卡驱动安装及故障排除
- 工欲善其事,必先利器—Regex正则表达式工具
- 基于STM32的ESP8266获取心知天气数据
- 【赠书】腾讯广告算法大赛冠军、Kaggle Grandmaster倾力打造,涵盖Kaggle、阿里天池等赛题...
- Word-embedding的资料整理
- 仿网易163的在线HTML编辑器及其轻量化结构
- FBX导入错误 :ImportFBX Errors:
- Retrofit请求 多条目加载