首页 > 其他分享 >TS泛型:接口、类、约束、类型推导与默认参数、泛型工具

TS泛型:接口、类、约束、类型推导与默认参数、泛型工具

时间:2024-05-24 21:28:39浏览次数:29  
标签:const name 推导 age TS 类型 泛型 string

泛型是用来创建可重用的组件的,是一种传递类型的方式,一个组件可以支持多种类型的数据

  • 常用的泛型标识符
    • T(Type):代表Type,在定义泛型时通常用作第一个类型变量名。
    • K(Key):表示对象中的键类型
    • V(Value):表示对象中的值类型
    • E(Element):表示元素类型

1. 泛型函数

在这里插入图片描述

2. 泛型接口

interface SearchFunc {
  (source: string, subString: string): boolean;
}
let mySearch: SearchFunc;

mySearch = function(source: string, subString: string) {
    return source.search(subString) !== -1;
}

3. 泛型类

interface GenericInterface<U> {
  value: U
  getIdentity: () => U
}

class IdentityClass<T> implements GenericInterface<T> {
  value: T
  constructor(value: T) {
    this.value = value
  }
  getIdentity(): T {
    return this.value
  }
}

const myNumberClass = new IdentityClass<Number>(68);
console.log(myNumberClass.getIdentity()); // 68
const myStringClass = new IdentityClass<string>("Semlinker!");
console.log(myStringClass.getIdentity()); // Semlinker!

实例化 myNumberClass 的调用过程:

  • 在实例化 IdentityClass 对象时,传入 Number 类型和构造函数参数值 68;
  • 之后在 IdentityClass 类中,类型变量 T 的值变成 Number 类型;
  • IdentityClass 类实现了 GenericInterface,而此时 T 表示 Number 类型,因此等价于该类实现了 GenericInterface 接口;
  • 而对于 GenericInterface 接口来说,类型变量 U 也变成了 Number。

4. 泛型约束

4.1. 确保属性存在:通过 extends 关键字添加泛型约束

希望类型变量对应的类型上存在 length 属性,让 T 具有 length 属性
实现:让类型变量 extends 一个含有 length 属性的接口

interface Length {
  length: number;
}

function identity<T extends Length>(arg: T): T {
  console.log(arg.length); // 可以获取length属性
  return arg;
}

当我们使用不含有 length 属性的对象作为参数调用 identity 函数时,TypeScript 会提示相关的错误信息:

identity(68); // Error
// Argument of type '68' is not assignable to parameter of type 'Length'.(2345)

还可以使用 , 号来分隔多种约束类型,比如:<T extends Length, Type2, Type3>

4.2. 检查对象上的键是否存在:keyof

keyof 操作符用于获取某种类型的所有键,返回类型是联合类型。

interface Person {
  name: string;
  age: number;
}

type PersonKeys = keyof Person; // "name" | "age"

function getValueByKey<T extends object, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

const person = {
  name: 'Bob',
  age: 25,
};

const name = getValueByKey(person, 'name'); // name 的类型是 string
const age = getValueByKey(person, 'age'); // age 的类型是 number
const gender = getValueByKey(person, 'gender'); // 编译报错,gender 不是 person 中的属性

在 中,extends 关键字表示限制 K 的取值只能是 T 类型中已有的属性名。也就是说,只有 K 取值为 T 类型中已有的属性名才符合类型约束

5. 类型推导与默认参数

5.1. 类型推导

function id<T>(arg: T): T {
  return arg;
}

id<string>("lucifer"); // 这是ok的,也是最完整的写法
id("lucifer"); // 基于类型推导,我们可以这样简写

5.2. 默认参数

interface A<T = string> {
  name: T;
}

const strA: A = { name: "Semlinker" };
const numB: A<number> = { name: 101 };

泛型参数的默认类型遵循以下规则:

  • 有默认类型的类型参数被认为是可选的。
  • 必选的类型参数不能在可选的类型参数后。
  • 如果类型参数有约束,类型参数的默认类型必须满足这个约束。
  • 当指定类型实参时,你只需要指定必选类型参数的类型实参。 未指定的类型参数会被解析为它们的默认类型。
  • 如果指定了默认类型,且类型推断无法选择一个候选类型,那么将使用默认类型作为推断结果。
  • 一个被现有类或接口合并的类或者接口的声明可以为现有类型参数引入默认类型。
  • 一个被现有类或接口合并的类或者接口的声明可以引入新的类型参数,只要它指定了默认类型。

6. 泛型工具

6.1. Partial:将类型T的所有属性转换为可选属性

interface Person {
  name: string;
  age: number;
}

const partialPerson: Partial<Person> = {
  name: 'John',
};
// partialPerson的类型为 Partial<Person>,即 { name?: string; age?: number; }

6.2. Record<K, T>:创建一个类型,其中键为类型K中的每个属性,并将它们映射到类型T。

interface PageInfo {
  title: string;
}

type Page = "home" | "about" | "contact";

const x: Record<Page, PageInfo> = {
  home: { title: "home" },
  about: { title: "about" },
  contact: { title: "contact" },
};

6.3. Pick<T, K>:从类型T中选择指定属性K。

interface Person {
  name: string;
  age: number;
  address: string;
}

type PersonNameAndAddress = Pick<Person, 'name' | 'address'>;
// PersonNameAndAddress的类型为 { name: string; address: string; }

6.4. Omit<T, K>:从类型T中排除指定属性K。

interface Person {
  name: string;
  age: number;
  address: string;
}

type PersonWithoutAge = Omit<Person, 'age'>;
// PersonWithoutAge的类型为 { name: string; address: string; }

6.5. ReturnType:获取函数类型T的返回类型。

function greet(name: string): string {
  return `Hello, ${name}!`;
}

type GreetReturnType = ReturnType<typeof greet>;
// GreetReturnType的类型为 string

标签:const,name,推导,age,TS,类型,泛型,string
From: https://blog.csdn.net/qq_36816794/article/details/139134897

相关文章

  • 不闭合三维TSP:蜣螂优化算法DBO求解不闭合三维TSP(起点固定,终点不定,可以更改数据集),MATLA
    一、旅行商问题旅行商问题(Travelingsalesmanproblem,TSP)是一个经典的组合优化问题,它可以描述为一个商品推销员去若干城市推销商品,要求遍历所有城市后回到出发地,目的是选择一个最短的路线。当城市数目较少时,可以使用穷举法求解。而随着城市数增多,求解空间比较复杂,无法使......
  • InfoTS: 具有信息感知增强的时间序列对比学习《Time Series Contrastive Learning wit
    现在是2024年5月23日,14:30,开始看论文。论文:TimeSeriesContrastiveLearningwithInformation-AwareAugmentations或者是:Timeseriescontrastivelearningwithinformation-awareaugmentationsGitHub:https://github.com/chengw07/InfoTSAAAI2023的论文。 摘要近年......
  • VBS(Visual Basic Script)是一种脚本语言,可以使用ADO(ActiveX Data Objects)来连接和操作A
    在PowerShell中,可以使用COM对象创建ADO连接并执行SQL查询来连接和操作Access数据库。以下是一个示例代码:powershellCopyCode#CreateaconnectiontoAccessdatabaseusingADO$conn=New-Object-ComObjectADODB.Connection$conn.Provider="Microsoft.ACE.OLEDB.12.0"......
  • vue + websocket + speak-tts 实现推送的告警消息弹框显示在右下角并语音播报出内容
    最近接了个项目需求,给设备配置语音加弹框告警。用户登录项目后不管在哪个页面,有告警就全局在右下角消息弹框加语音播报,下面浅介绍下我在开发中的流程以及遇到的坑!!!1、首先项目中安装speak-tts语音播报插件。npminstallspeak-tts2、创建一个全局的speech.js文件,文件中引入插......
  • TypeScript中的嵌套泛型
    当我们讨论嵌套泛型时,让我们以一个简单的示例来说明。假设我们有一个泛型类型`Container`,它接受两个类型参数:`T`和`U`。其中`T`表示容器中的数据类型,而`U`则表示某种附加信息的类型。```typescript//定义一个泛型类型ContainertypeContainer<T,U>={data:T;info......
  • 低代码与 Echarts 融合:开启智能可视化的创新浪潮
    前言在当今数字化时代,数据的价值愈发凸显,企业和组织需要有效地利用数据来作出战略决策和优化业务流程。可视化是一种强大的工具,可以将复杂的数据以直观的方式展现出来,帮助用户更好地理解和分析数据。近年来,低代码开发平台和Echarts可视化库的结合,为智能可视化带来了全新的创新......
  • vue3+ts购物车demo
    <template><div><h1>ShoppingCart</h1><button@click="addItem">AddItem</button><button@click="deleteSelectedItems">DeleteSelectedItems</button><button@c......
  • PowerShell 中重置SQL SERVER数据库的 SA(System Administrator)密码可以通过 SQL Serve
    PowerShell中重置数据库的SA(SystemAdministrator)密码可以通过SQLServerManagementObjects(SMO)来完成。以下是一个基本的PowerShell脚本,可以用来重置SA用户的密码:powershellCopyCode#导入SQLServer模块Import-ModuleSQLPS-DisableNameChecking#设置SQL......
  • HDLBits/状态机笔记
    `moduletop_module(inputclk,inputx,outputz);reg[2:0]s_cur;reg[2:0]s_nex;//传递状态always@(posedgeclk)begins_cur<=s_nex;end//确定下一状态always@()begincase(s_cur)3'b000:case(x)0:s_nex=3'b100;1:s_nex=3'b111;endcase3�......
  • TS类,接口,泛型的简介
    //1.类的属性和方法classDog{name:string="旺财";age:number=2;shout(){console.log("汪汪汪")}}letdog=newDog()//2.类的构造函数(用于给类中的属性设定初始值,在创建类的实例时会被触发)classCat{name:string;ag......