当前位置: 首页 > article >正文

TS 函数及多态

 TS 能推导出函数体中的类型,但多数情况下无法推导出参数的类型,只有少数特殊情况下能根据上下文推导参数的类型。返回类型能推导出,不过也可以显式注解。

1 声明和调用函数

一般来说,在方法中的this值为调用该方法时位于点号左侧的对象:

let x = {
    fun() {
        console.log(this);
    }
}
x.fun(); // { fun: [Function: fun] }
let fun = x.fun;
fun(); // undefined

如果在函数中有使用到this,则上面的方法定义是可能会带来风险的(this不能保证为想要的类型)。

我们可以在函数的第一个参数中,声明this的类型,来规避上面的风险。

let x = {
    fun(this: Date) {
        console.log(this.getDate());
    }
}
let date = new Date();
x.fun.bind(date)(); // 27
//x.fun(); // The this context of type { fun(this: Date): void; } is not assignable to method's this of type Date

1.1 函数类型重载

重载函数,即有多个调用签名的函数。

type Reserve = {
    (from: Date, to: Date, destination: String):String,
    (from: Date, destination: String):String
}
let reserve: Reserve = (from: Date, to: Date | String,destination?: String) => {
    return "destination:" + destination;
}
reserve(new Date(), new Date(),"hello");
reserve(new Date(),"ts");

注意,我们在调用函数时,参数类型不是参照这个函数定义时的类型,而是这个函数的签名,例如上面,如果参照函数定义,则函数调用可以为:

图 函数调用失败

如上图所示,上面的调用方式将会报错。

1.1.1 DOM 中的重载

浏览器DOM API有大量重载,例如createElement方法。参数为表示HTML标签的字符串,返回值为对应类型的HTML元素,其函数定义为:

type CreateElement = {
    (tag: 'a'): HTMLAnchorElement,
    (tag: 'canvas'): HTMLCanvasElement,
    (tag: 'table'): HTMLTableElement,
    (tag: string): HTMLElement
}

2 多态

在类型层面施加约束的占位类型,也称多态类型参数。

type Filter = {
    <T>(array: T[], f: (item: T) => boolean): T[]
}
let filter: Filter = (array, f) => {
    let arr = []
    for (let item of array) {
        if (f(item)) arr.push(item);
    }
    return arr;
}
filter([2,5,7,6],(_) => _ > 5); // [7,6]

<T>在调用签名中声明(位于签名的开始圆括号前面),TS将在调用该类型的函数时为T绑定具体类型。

而如果把T的作用域限定在类型别名中,TS则要求在使用类型别名时显式绑定类型:

type Filter<T> = {
    (array: T[], f: (item: T) => boolean): T[]
}
let filter: Filter<number> = (array, f) => {
    let arr = []
    for (let item of array) {
        if (f(item)) arr.push(item);
    }
    return arr;
}
filter([2,5,7,6],(_) => _ > 5); // [7,6]

2.1 受限的多态

TS 多态可以像Java一样使用extends来约束多态(但不能使用super)。

type TreeNode = {
    value: string
}
type LeafNode = TreeNode & {
    isLeaf: true
}
type InnerNode = TreeNode & {
    children: [TreeNode] | [TreeNode,TreeNode]
}
function mapNode<T extends TreeNode>(node: T,f: (value: string) => string) : T {
    return {
        ...node,
        value: f(node.value)
    }
}

2.2 泛型默认类型

泛型参数可以指定默认类型。

type AString = {
    value: "a"
}
type BNum = {
    num: 1
}
type MyString<T extends AString = AString & BNum> = {
    value: T
}
let myString: MyString = {
    value: { value: "a", num: 1}
}

http://www.kler.cn/a/147055.html

相关文章:

  • android四大组件之一——Service
  • 计算机网络期末复习(知识点)
  • LLaMA-Factory web微调大模型并导出大模型
  • Windows10-用户账户控制、Windows远程桌面
  • 解决:前端js下载文件流出现“未知文件格式”错误
  • C语言重点编程题——11-20
  • Android 编译系统AIDL模块couldn‘t find import for class错误
  • leetcode42接雨水问题
  • Javascript每天一道算法题(十八)——矩阵置零-中等
  • 带你用uniapp从零开发一个仿小米商场_10. 首页开发
  • MATLAB算法实战应用案例精讲-【图像处理】图像增强
  • go 在使用Elasticsearch 聚合查询时 如何设置使用中国时区
  • C语言第三十五弹---打印九九乘法表
  • 【JMeter】不同场景下的接口请求
  • Sass基础知识详细讲解【附带表图】
  • ubuntu22.04 安装 jupyterlab
  • C#中警告IDE0290、IDE1006、IDE1100、IDE0251、IDE0300及处理
  • flutter 输入框组件 高度问题
  • 大语言模型:以Amazon Titan等大语言模型为例介绍
  • Vue简易的车牌输入键盘,可以根据需要修改
  • 如何搭建zerotier服务器组网实现内网穿透
  • AIGC技术的未来趋势:创新、智能化与社会影响
  • Java八股文面试全套真题【含答案】- Linux篇