TypeScript中泛型的使用详细讲解

作者:郑建007 时间:2024-04-17 10:35:23 

一、泛型程序设计是一种编程风格或编程范式

二、案例:传入的参数类型与返回的类型一样

function identify<T>(arg: T): T {// 当前的T没有任何约束 它可以是任何类型
   return arg;
}

const foo = identify('foo'); // foo的类型是'foo'
const bar = identify('true'); // bar的类型是true

三、形式类型参数

 1、形式类型参数T的默认类型为boolean类型

<T = boolean>

2、必选类型参数、可选类型参数

(1)、必选类型参数:形式类型参数没有给默认类型 , 例如: <T>

(2)、可选类型参数:形式类型参数给默认类型 , 例如: <T = boolean>

(3)、形式类型参数列表中,必选类型参数不允许出现在可选类型参数之后

<T = boolean, U> // 错误
<T, U = boolean> // 正确

四、泛型约束

在形式类型参数上允许定义一个约束条件,它能够限定类型参数的实际类型的最大范围。我们将类型参数的约束条件称为泛型约束

interface point {
   x: number,
   y: string
}

function getPoint<T extends point>(args: T): T {
   return args
}

console.log(getPoint({x: 123, y: 456})); // 错误
console.log(getPoint({x: 123, y: '456'})); // 正确
console.log(getPoint({x: 123, y: '456', z: 678})); // 正确
//参数的前俩个必须有并且类型必须正确  否则错误

可以同时定义泛型约束和默认类型

<T extends number = 0 | 1>

泛型约束 ==> 类型参数

<T, U extends T>
<T extends U, U>

形式类型参数不允许直接或间接地将其自身作为约束类型

<T extends T> // 错误
<T extends U, U extends T> // 错误

类型参数T没有声明泛型约束,那么类型参数T的基约束为空对象类型字面量&ldquo;{}&rdquo;。除了undefined类型和null类型外,其他任何类型都可以赋值给空对象类型字面量

<T> // 类型参数T的基数约为“{}”类型

五、泛型函数

1.简介:若一个函数的函数签名(形参)中带有类型参数,那么它是一个泛型函数 

2.f1函数两个参数的类型相同,函数返回值类型是数组,数组元素类型 == 参数类型。

function f1<T>(x: T, y: T): T[] {
   return [x, y]
}

const a = f1(123, 456)
const b = f1('123', '456')

3.f2函数两个参数的类型不同,返回值类型为对象类型。返回值对象类型中x属性的类型与参数x类型相同,y属性的类型与参数y类型相同

function f2<T, U>(x: T,  y: U): { x: T, y: U} {
   return { x, y }
}

const a = f2('123', 456)
const b = f2(123, '456')

4.f3函数接受两个参数,参数a为任意类型的数组;参数f是一个函数,该函数的参数类型与参数a的类型相同,并返回任意类型。f3函数的返回值类型为参数f返回值类型的数组。

(这个代码的粘贴的   我也懵逼)

function f3<T, U>(a: T[], f: (x: T) => U): U[] {
   return a.map(f);
}

// f3<number, boolean> 约束T为number类型  U为boolean类型
const a: boolean[] = f3<number, boolean>([1, 2, 3], n => !! n)

六、泛型函数类型推断

function f0<T>(x: T): T {
   return x
}

const a = f0(123) // 推断出类型为 123
const b = f0('123') // 推断出类型为 '123'

此例中编译器推断出的不是number 和 string类型,而是字符串字面量类型123和&ldquo;123&rdquo;。因为TS原则,始终将字面量视为字面量类型,只在必要的时候才会将字面量类型放宽为某种基础类型,例如string类型。此例中,字符串字面量类型&ldquo;123&rdquo;是比string类型更加精确的类型。

类型参数只在函数签名中出现一次,则说明它与其他值没有关联,则不需要使用类型参数,直接声明实际类型即可。

几乎任何函数都可以声明为泛型函数。若泛型函数的类型参数不表示参数之间或参数与返回值之间的某种关系,那么使用泛型函数可能是一种反模式。

// 没必要使用泛型
function f<T>(x: T): void {
   console.log(x)
}

// 直接限定就好了
function f(x: number): void {
   console.log(x)
}

补充:应用场景

通过上面初步的了解,后述在编写 typescript 的时候,定义函数,接口或者类的时候,不预先定义好具体的类型,而在使用的时候在指定类型的一种特性的时候,这种情况下就可以使用泛型

灵活的使用泛型定义类型,是掌握typescript 必经之路

<泛型变量名称>(参数1: 泛型变量, 参数2: 泛型变量, ...参数n: 泛型变量) => 泛型变量

/*------------基础使用方法------------*/
 function join<T, P>(first: T, second: P): T {
   return first;
 }
 //const twoParms = join<number, string>(1, '我是string');
 const twoParms = join(1, '我是string');

/*---------泛型集合--------------*/
 function map<T>(params: Array<T>) {
   return params;
 }
 //const sanleType = map<string>(['123']);
 const sanleType = map(['123']);

/* -----------泛型箭头函数-------------*/
 const identity = <T,>(arg: T): T => {
   return arg;
 };
 const identity2: <T>(arg: T) => T = (arg) => {
   return arg;
 };

泛型接口

/* -------------泛型接口-------------*/
interface ColumnProps<T> {
 key: number | string;
 title: string;
 dataIndex: keyof T; // 约束 dataIndex 值需为引用泛型 T 中的属性
}
interface ITableItem {
 key: number | string;
 name: string;
 address: string;
 age: number;
}
const columns: Array<ColumnProps<ITableItem>> = [
   {
     title: '姓名',
     dataIndex: 'name',
     key: 'name',
   },
 ];

泛型类

/*--------------泛型类---------------*/
 class Person<T> {
   love: T;
   say: (arg: T) => T;
 }
 let myFn: IGeneric<number> = fn;
 myFn(13); //13

let me = new Person<string>();
 me.love = 'TS';
 // me.love = 520; // ERROR
 me.say = function(love: string){
   return `my love is ${love}`;
 }

泛型约束

泛型可以通过 extends 一个接口来实现泛型约束,写法如:

<泛型变量 extends 接口>

<T, K extends keyof T>
//K为传入的T上已知的属性,

interface IArray {
 length: number
}
function logIndex<T extends IArray>(arg: T): void {
 for (let i = 0; i < arg.length; ++i) {
   console.log(i)
 }
}
let arr = [1, 2, 3]
// logIndex<number>(arr) // 报错
logIndex<number[]>(arr) // 允许
logIndex(arr) // 自动类型推导,允许

泛型应用场景之一

/*-------------应用场景start---------------------------*/
interface ColumnProps<T> {
 key: number | string;
 title: string;
 dataIndex: keyof T; // 约束 dataIndex 值需为引用泛型 T 中的属性
}
interface ITableItem {
 key: number | string;
 name: string;
 address: string;
 age: number;
}
interface TableProps {
 dataSource: ITableItem[];
 columns: Array<ColumnProps<ITableItem>>;
}
const MyTable = (props: TableProps) => {
 const { dataSource, columns } = props;
 return <Table dataSource={dataSource} columns={columns} />;
};
const ApplcationMod = () => {
 const dataSource = [
   {
     key: '1',
     name: '金城武',
     age: 32,
     address: '西湖区湖底公园1号',
   },
   {
     key: '2',
     name: '吴彦祖',
     age: 42,
     address: '西湖区湖底公园1号',
   },
 ];

const columns: Array<ColumnProps<ITableItem>> = [
   {
     title: '姓名',
     dataIndex: 'name',
     key: 'name',
   },
   {
     title: '年龄',
     dataIndex: 'age',
     key: 'age',
   },
   {
     title: '住址',
     dataIndex: 'address',
     key: 'address',
   },
 ];

return (
   <div>
     <h3>泛型应用场景</h3>
     <MyTable dataSource={dataSource} columns={columns} />
   </div>
 );
};

来源:https://blog.csdn.net/qq_52421092/article/details/127636771

标签:typescript,泛型
0
投稿

猜你喜欢

  • Python设计模式中的状态模式你了解吗

    2023-07-14 08:20:28
  • SQL Server与Oracle数据库在查询优化上的差异

    2009-02-18 14:28:00
  • Python解惑之True和False详解

    2022-06-02 20:28:03
  • python模拟事件触发机制详解

    2023-03-11 11:09:02
  • 解析SQL Server 2008中的新语句:MERGE

    2009-01-13 13:57:00
  • numpy:np.newaxis 实现将行向量转换成列向量

    2023-07-13 03:14:39
  • ORACLE应用经验(2)

    2010-07-31 13:31:00
  • 教你怎么用Python生成九宫格照片

    2023-12-02 17:20:51
  • 零基础学习python偏函数语法的推导方法步骤

    2021-07-17 20:59:18
  • 对pandas中两种数据类型Series和DataFrame的区别详解

    2021-08-05 04:09:38
  • Python使用socket实现组播与发送二进制数据

    2021-05-09 13:44:28
  • 基于Python实现开心消消乐小游戏的示例代码

    2022-03-20 13:19:10
  • 浏览器tab的设计

    2008-08-11 13:03:00
  • Python实现计算两个时间之间相差天数的方法

    2022-11-09 06:04:59
  • django中forms组件的使用与注意

    2021-03-11 00:14:04
  • django 使用全局搜索功能的实例详解

    2023-01-26 05:56:56
  • 用python打印1~20的整数实例讲解

    2023-12-18 21:45:06
  • 详解Python的Django框架中的templates设置

    2021-12-15 15:16:06
  • python opencv设置摄像头分辨率以及各个参数的方法

    2021-03-05 00:23:34
  • 图片完美缩放

    2024-04-22 13:07:22
  • asp之家 网络编程 m.aspxhome.com