TypeScript - 函数(上)

news2024/12/23 18:41:41

目录

1、介绍 

2、函数类型表达式

3、呼叫签名

4、构造签名

5、泛型函数

6、推论

7、约束

8、使用约束值

9、指定类型参数


1、介绍 

函数是JavaScript应用程序的基础。 它帮助你实现抽象层,模拟类,信息隐藏和模块。 在TypeScript里,虽然已经支持类,命名空间和模块,但函数仍然是主要的定义 行为的地方。函数是任何应用程序的基本构建块,无论它们是本地函数、从其他模块导入的函数,还是类上的方法。 它们也是值,就像其他值一样,TypeScript 有很多方法来描述如何调用函数。 让我们学习如何编写描述函数的类型。

2、函数类型表达式

描述函数的最简单方法是使用函数类型表达式。 这些类型在语法上类似于箭头函数:

function Animal(fn: (age: number)=>void){
    return fn(20);
}

function Cat(age: number) {
    console.log('age: ', age);
}

// age:  20
Animal(Cat) 

语法(age: number) => void 表示“具有一个参数的函数,参数为数字类型,没有返回值”。 就像函数声明一样,如果未指定参数类型,则是隐式的 any 类型。

fn: (age: number)=>void 形成一个函数表达式,参数是必须的,需声明对应的类型,否则具有隐藏式的类型 any。

我们可以把函数类型表达式赋值给类型别名,如下所示:

type expFunc = (age: number) => void;

function Animal(fn: expFunc) {
    return fn(20);
}

function Cat(age: number) {
    console.log('age: ', age);
}

// age:  20
Animal(Cat) 

3、呼叫签名

在 JavaScript 中,函数除了可调用之外,还可以具有属性。 但是,函数类型表达式语法不允许声明属性。 如果我们想描述一些可以用属性调用的东西,我们可以在对象类型中写一个调用签名

type DescInfo = {
    desc: string;
    (args: number): number
};

function Animal(fn: DescInfo) {
    // 我是tom🐱今年2岁
    console.log(fn.desc + '今年' +fn(2) + '岁');
}

function Cat(age: number) {
    return age;
}
Cat.desc = "我是tom🐱";

Animal(Cat)

请注意,与函数类型表达式相比,语法略有不同 - 在参数列表和返回类型之间使用,而不是上面缩写的(fn: (age: number)=>void)这样。

4、构造签名

JavaScript 函数也可以与运算符一起调用。 TypeScript 将这些称为构造函数,因为它们通常会创建一个新对象。 您可以通过在呼叫签名前面添加关键字来编写构造签名new

type DescInfo = {
   new (args: number): Cat
};

function Animal(fn: DescInfo) {
    return new fn(20);
}

class Cat {
    age: number;
    constructor(age: number){
        this.age = age;
    }
}

console.log(new Cat(20).age);  // 20

某些对象,如 JavaScript 的对象,可以带或不带 . 您可以任意组合同一类型的调用和构造签名:

interface Animal {
    new(name: string, birthday: Date);
    (n?:number): number; 
}

5、泛型函数

通常编写一个函数,其中输入的类型与输出的类型相关,或者两个输入的类型以某种方式相关。

function Animals(array: any[]) {
    return array[1];
}

如果函数返回数组元素的类型会更好,例如:any 或者其他类型

在 TypeScript 中,当我们想要描述两个值之间的对应关系时,会使用泛型。 我们通过在函数签名中声明一个类型参数来做到这一点:

function Animals<Type>(array: any[]) : Type | undefined {
    return array[1];
}

在函数定义是,指定泛型Type,在返回的时候也指定对应类型 Type | undefined,这样返回的结果就会事先定义的范围,这样也使得结果更可控。

function Animals<Type>(array: any[]) : Type | undefined {
    return array[1];
}
console.log(Animals([1,2])); // 2

6、推论

我们不必在此示例中指定。 类型是由 TypeScript 推断的 - 自动选择的。

我们也可以使用多个类型参数。 例如

function Animals<Input, Output>(arr: Input[], func: (arg: Input) => Output) : Output[] {
    return arr.map(func)
}
Animals([1,2,3], (n)=>console.log(n)); // 1 2 3

7、约束

我们编写了一些可以处理任何类型的值的通用函数。 有时我们想关联两个值,但只能对某个值子集进行操作。 在这种情况下,我们可以使用约束来限制类型参数可以接受的类型类型。

function longest<Type extends { length: number }>(a: Type, b: Type) {
    if (a.length >= b.length) {
      return a;
    } else {
      return b;
    }
  }

  const longerArray = longest([1, 2], [1, 2, 3]);
  const longerString = longest("alice", "bob");
  const notOK = longest(123, 100);

// longest 指定类型必须有长度 ,字符串和数组都有长度,而数组没有length 

在此示例中,有一些有趣的事项需要注意。 我们允许 TypeScript 推断返回类型 。 返回类型推理也适用于泛型函数(longest)。

因为我们被限制为 ,所以我们被允许访问 和 参数的属性。 如果没有类型约束,我们将无法访问这些属性,因为这些值可能是没有 length 属性的其他类型的值。Type{ length: number }.length a b

和的类型是根据参数推断的。 请记住,泛型都是关于将两个或多个值与同一类型相关联!longerArraylongerString

8、使用约束值

function minimumLength<Type extends { length: number }>(
  obj: Type,
  minimum: number
): Type {
  if (obj.length >= minimum) {
    return obj;
  } else {
    return { length: minimum }; // 报错...
  }
}

发现else里面的return,报错了,如下所示: 

不能将类型“{ length: number; }”分配给类型“Type”。
"{ length: number; }" 可赋给 "Type" 类型的约束,但可以使用约束 "{ length: number; }" 的其他子类型实例化 "Type"。

如果返回是Type类型,可以调用函数试一下

const arr = minimumLength([1, 2, 3], 6);
console.log(arr.slice(0)); // [1, 2, 3]

如果把上面返回值改成obj,之后,上面代码是可以执行。

9、指定类型参数

TypeScript 通常可以在泛型调用中推断预期的类型参数,但并非总是如此。 例如,假设您编写了一个函数来组合两个数组:

function arrayConcat<Type>(arr1: Type[], arr2: Type[]): Type[] {
  return arr1.concat(arr2);
}

下面测试一下,传不同类型是否会报错提示:

console.log(arrayConcat([1,2,3], ['name']));  // 不能将类型“string”分配给类型“number”。
console.log(arrayConcat([1,2,3], [true]));    // 不能将类型“boolean”分配给类型“number”。
console.log(arrayConcat([1,2,3], [4, 5, 6]));    
console.log(arrayConcat([1,2,3], [undefined]));
console.log(arrayConcat([1,2,3], [null]));

根据以上测试结果,可以看出前2种会有对应错误提示。

如果能提前知道类型的参数,可以提前指定类型参数。如下所示:

console.log(arrayConcat<number | string>([1,2,3], ['name']));  
console.log(arrayConcat<number | boolean>([1,2,3], [true])); 

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

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

相关文章

Linux——进程的概念

task_struct task_struct 是linux下管理进程的结构&#xff0c;称为PCB&#xff0c;进程控制块。linux所有的指令本质上都是一个进程。进程 task_struct 进程的数据、代码、可执行程序&#xff0c;有属性、有内容。 进程是系统的工作单元。系统由多个进程组成&#xff0c;包…

Linux定时任务--crontab

linux内置了cron进程&#xff0c;cron搭配shell脚本&#xff0c;就可以完成特定的需求&#xff0c;有定时任务的效果。 crontab指令即cron table的简写&#xff0c;相关的配置文件目录如下&#xff1a; /var/spool/cron/ 目录下存放的是每个用户包括root的crontab任务&#xf…

论文笔记--On the Sentence Embeddings from Pre-trained Language Models

论文笔记--On the Sentence Embeddings from Pre-trained Language Models 1. 文章简介2. 文章概括3 文章重点技术3.1 BERT模型的语义相似度能力分析3.2 Anistropic各向异性3.3 BERT-flow3.4 Flow-based model 4. 文章亮点5. 原文传送门6. References 1. 文章简介 标题&#x…

树莓派Pico|RP2040简介|PINOUT|点灯示例

文章目录 一、Pico简介&#xff1a;二、几个比较重要的git仓库&#xff1a;三、使用前必读&#xff1a;四、PINOUT五、点灯一、如何安装固件二.安装Thonny编程环境配置三、点亮板载的LED灯Pico点亮板载LED灯的代码&#xff1a;PicoW点亮板载LED灯的代码&#xff1a; 一、Pico简…

[LeetCode周赛复盘] 第 107 场双周赛20230624

[LeetCode周赛复盘] 第 107 场双周赛20230624 一、本周周赛总结6898. 字符串连接删减字母1. 题目描述2. 思路分析3. 代码实现 6895. 构造最长的新字符串1. 题目描述2. 思路分析3. 代码实现 6898. 字符串连接删减字母1. 题目描述2. 思路分析3. 代码实现 6468. 统计没有收到请求…

Linux系统之部署Dailynotes个人笔记管理工具

Linux系统之部署Dailynotes个人笔记管理工具 一、Dailynotes介绍二、本地环境介绍2.1 本地环境规划2.2 本次实践介绍 三、检查本地环境3.1 检查本地操作系统版本3.2 检查系统内核版本3.3 检查本地yum仓库状态 四、部署Node.js 环境4.1 下载Node.js安装包4.2 解压Node.js安装包4…

ThreadPoolExecutor的应用

前面描述的线程池的创建方式大都是Executors类中创建出来&#xff0c;基于ThreadPoolExecutor去new出来实现的。 我们为什么要自定义线程池 在线程池ThreadPoolExecutor中提供了7个参数&#xff0c;都作为非常核心的属性&#xff0c;在线程池去执行任务的时候&#xff0c;每个…

Nginx-Goaccess(实时日志服务)

goaccess的功能 1、使用webscoket协议传输&#xff08;双向传输协议&#xff09;2、基于终端的快速日志分析器3、通过access.log快速分析和查看web服务的统计信息、PV、UV4、安装简单、操作简易、界面炫酷5、按照日志统计访问次数、独立访客数量、累计消耗的带宽6、统计请求次…

物理引擎--Open Dynamics Engine(ODE)

物理引擎--Open Dynamics Engine--ODE 1 介绍1.1 概述1.2 代码1.3 wiki1.4 特征1.5 许可 2 安装使用3 概念3.1 背景3.2 刚体3.2.1 岛屿和禁用实体 3.3 一体化3.4 积分器3.5 关节和约束3.6 关节组3.7 关节误差和误差减少参数 (ERP) Joint error and the Error Reduction Paramet…

Scala函数式编程【从基础到高级】

目录 函数基础 基本语法 函数参数 函数至简原则 至简原则细节 函数高级 高阶函数 函数的3种高阶用法&#xff1a; 1、函数作为值传递 2、函数作为参数传递 匿名函数作参数传递 3、函数作为返回值传递 匿名函数的至简规则 高阶函数的应用 案例-将数组中的元素全部…

【LeetCode】 动态规划 刷题训练(三)

文章目录 931. 下降路径最小和题目解析状态转移方程完整代码 64. 最小路径和题目解析状态转移方程完整代码 174. 地下城游戏题目解析状态转移方程完整代码 931. 下降路径最小和 点击查看&#xff1a;下降路径最小和 给你一个 n x n 的 方形 整数数组 matrix &#xff0c;请你找…

chatgpt赋能python:Python搜题软件:为你量身定制的智能搜索助手

Python搜题软件&#xff1a;为你量身定制的智能搜索助手 随着互联网的普及&#xff0c;我们每天需要面对海量的信息&#xff0c;其中包含了我们所需要的一切答案。但是&#xff0c;如何快速而准确地找到这些答案呢&#xff1f;这时候&#xff0c;一款智能化的搜题软件就非常有…

【不推荐】win 安装 rust 1.70 (MSVC)

目录 一、下载二、安装三、配置环境变量四、检查是否安装成功五、参考文章 一、下载 官网地址&#xff1a;https://www.rust-lang.org/zh-CN/ https://forge.rust-lang.org/infra/other-installation-methods.html 历史版本下载地址&#xff1a; 二、安装 注意&#xff1a;安…

Redis:redis基于各大实战场景下的基本使用

文章目录 前言String 命令实战1.业务缓存对应redis中的指令伪代码 2.分布式锁对应redis中的指令伪代码 3.限流对应redis中的指令伪代码 List 命令实战1.提醒功能对应Redis中的指令伪代码 2.热点列表对应Redis中的指令伪代码 Hash 命令实战1.用户资料缓存对应redis中的指令伪代码…

RabbitMQ学习笔记(尚硅谷)

文章目录 一. 消息队列1. 定义2. 作用2.1 流量消峰2.2 应用解耦2.3 异步处理 3. 分类4. MQ的选择5. RabbitMQ5.1 概念5.2 四大概念5.3 六大模式5.4 RabbitMQ 工作原理5.5 安装 6. 代码实现 二. Hello World (简单模式)1. 生产者代码2. 消费者代码 三. Work Queues (工作队列模式…

OUC编译原理实验报告 实验5:用Yacc设计语法分析器1 实验6:用Yacc设计语法分析器2

编译原理实验报告 实验5&#xff1a;用Yacc设计语法分析器1 实验6&#xff1a;用Yacc设计语法分析器2 中国海洋大学编译原理实验2023春 仅供同学参考思路 请勿直接抄袭 否则可能喜提0分 目录 文章目录 编译原理实验报告目录一.实验目的二.实验内容实验5实验6 三.实验要求实…

RISCV Reader笔记_2 RV32I

RV32I 完整的RV32I指令集可以用下面的式子中出现单词的首字母表示&#xff1a; 比如这一条&#xff1a; set less than {immediate} {unsigned} 也就是slt slti sltu sltiu这4个指令。 RISCV指令格式如下。R 寄存器操作&#xff0c;I 立即数或load访存&#xff0c;S store访…

C51单片机期末复习第八章单片机接口技术

一 总线&#xff1a; 传送同类信息的连线 三总线&#xff1a; 地址总线AB&#xff0c;数据总线DB,控制总线CB 目录(ppt给的没啥用&#xff0c;乱还不全)&#xff1a; 8.1 单片机的系统总线 8.2 简单并行I/O口扩展 8.3 可编程并行I/O口扩展 8.4 D/A转换与DAC0832应用 8…

稀疏表:最大公约数

问题描述 给定一个数组, 每次操作可以选择数组中任意两个相邻的元素 x , y x, y x,y 并将其 中的一个元素替换为 gcd ⁡ ( x , y ) \operatorname{gcd}(x, y) gcd(x,y), 其中 gcd ⁡ ( x , y ) \operatorname{gcd}(x, y) gcd(x,y) 表示 x x x 和 y y y 的最大公约数。 请…

MIT 6.S081 教材第五章内容 -- 中断与设备驱动--下

MIT 6.S081 教材第五章内容 -- 中断与设备驱动--下 引言关于RISC-V特权级架构说明RISC-V特权模式OpenSBI介绍RISC-V启动过程RISC-V中的异常M模式下的异常1. 硬件中断的处理&#xff08;以时钟中断为例&#xff09;2. M模式下的异常相关寄存器3. 同步异常的处理 S模式下的异常1.…