泛型什么

泛型是 TypeScript比较高级功能之一,
泛型应用场景非常广泛,平时我们阅读开源 TS 项目源码,或者在自己的 TS 项目中使用一些第三方库(比如 React)的时候,经常会看到各种泛型定义

泛型允许我们定义时候不具体指定类型,而是泛泛地说一种类型,并在函数调用时候指定具体的参数类型
就是泛型也是一种类型,只不过不同string, number 等具体的类型,它是一种抽象类型我们不能直接定义一个变量类型泛型

为什么使用泛型?

假如我们实现一个函数fn函数参数可以是任何值,返回值就是参数原样返回,并且其只能接受一个参数应该怎么做?

一般在可能顺手写出一行代码

const fn = (arg) => arg;

接下来我们给它加上类型声明

type fnBoolean = (arg: boolean) => boolean;
type fnNumber = (arg: number) => number;
type fnString = (arg: string) => string;

虽然看着简单,但是js提供多少类型就写多少然后声明类型,这样代码出错率会提高,而且代码难以维护,牵一发而动全身。并且将来 JS 新增新的类型,仍然需要修改代码,很麻烦。
有一种解决方法是使用any类型这种“万能语法”,但是使用any后虽然怎么写都行,但是这样也就失去了ts类型检查的意义。
因此,,我们使用泛型对上面的代码进行重构。和我们的定义不同这里用了一个 类型 T,这个T 是一个抽象类型,只有在调用时候确定它的值。

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

泛型的基本使用

函数中使用

function fn<T> (arg:T):T{
  return arg;
}
fn<number>(666);// 返回值number类型 666
fn<string>('黄雨萌')//返回值string类型 黄雨萌
fn<boolean>(true);//返回值是布尔类型 true

就是刚才提到的,需要什么类型就可以什么类型,类似于函数传参

fn(666)
fn('黄雨萌')
fn(true)

编译器自动识别传入的参数,将传入的参数的类型认为是泛型指定的类型,效果是一样的

接口中使用

interface person {
    <T, Y>(name: T, age: Y): T
}
let people:person = function(name,age){
    return name
}
people("黄雨萌", 18)

类中使用

class Friends<T, Y> {
    name: T
    age: Y
    constructor(name:T, age:Y) {
        this.name = name
        this.age = age
    }
}
let wife = new Friends("黄雨萌", 18) // 实例对象 Friends{name: '黄雨萌', age: 18}

泛型约束

使用接口约束泛型

interface Person {
    name: string,
    age: number
}

function girl<T extends Person>(obj: T): T {
    return obj
}
girl({ name: "黄雨萌" }) // 类型“{ name: string; }”的参数不能赋给类型“Person”的参数 类型 "{ name: string; }" 中缺少属性 "age",但类型 "Person" 中需要属性
girl({ name: "黄雨萌", age: "18" }) // 不能将类型“string”分配给类型“number
girl({ name: "黄雨萌", age: 18 })

数组泛型

let arr11: Array<number> = [1, 2, 3]
let arr22: number[] = [1, 2, 3]

两种写法是一样的效果

泛型工具类型

未完待续

在这里插入图片描述

原文地址:https://blog.csdn.net/m0_65349389/article/details/128350577

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_37274.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注