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

浙江建设工程造价信息网站wordpress单主题

浙江建设工程造价信息网站,wordpress单主题,建设网站需要花费多少钱,asp 公司网站源码如果说 TypeScript 是一门对类型进行编程的语言,那么泛型就是这门语言里的(函数)参数。本章,我将会从多角度讲解 TypeScript 中无处不在的泛型,以及它在类型别名、对象类型、函数与 Class 中的使用方式。 一、泛型的核…

如果说 TypeScript 是一门对类型进行编程的语言,那么泛型就是这门语言里的(函数)参数。本章,我将会从多角度讲解 TypeScript 中无处不在的泛型,以及它在类型别名、对象类型、函数与 Class 中的使用方式。

一、泛型的核心概念

1.基本定义

泛型(Generics)是 TypeScript 中允许在定义函数、接口或类时不预先指定具体类型,而是在使用时动态指定类型的机制。其核心目标是实现代码的可重用性类型安全

  • 示例
    function identity<T>(arg: T): T { return arg; }

    此处 <T> 为类型参数,T 在调用时被具体类型替换,如 identity<string>("hello")

  • 不过上述例子中直接  identity("hello") 也是可以的,省略不写类型参数的值,让 TypeScript 自己推断。但有些复杂的使用场景,TypeScript 可能推断不出类型参数的值,这时就必须显式给出了。

    function comb<T>(arr1:T[], arr2:T[]):T[] {return arr1.concat(arr2);
    }comb([1, 2], ['a', 'b']) // 报错comb<number|string>([1, 2], ['a', 'b']) // 正确

    上面示例中,两个参数arr1arr2和返回值都是同一个类型。如果不给出类型参数的值,调用会报错。如果类型参数是一个联合类型,就不会报错。

2. 泛型 vs any

  • any 的缺陷:放弃类型检查,失去 TypeScript 的类型安全优势。
  • 泛型的优势:保留类型信息,编译器可进行静态检查,如类型推断与错误提示 。

二、泛型的主要应用场景

泛型主要用在四个场合:函数、接口、类和别名。

1. 函数的泛型写法

通过泛型定义可处理多种类型的函数,避免重复代码:

function reverse<T>(items: T[]): T[] {return items.reverse();
}
const numbers = reverse([1, 2, 3]); // 推断为 number[]
const strings = reverse(["a", "b"]); // 推断为 string[]

此例中,T 自动匹配输入数组类型,返回值类型与输入一致。

2. 接口的泛型写法

定义灵活的类型契约,适用于容器类场景:

interface KeyValuePair<K, V> {key: K;value: V;
}
const pair: KeyValuePair<number, string> = { key: 1, value: "one" };

接口通过类型参数 KV 支持多种键值组合。

3. 类的泛型写法

创建可复用的数据结构(如集合、栈、队列):

class Stack<T> {private items: T[] = [];push(item: T) { this.items.push(item); }pop(): T | undefined { return this.items.pop(); }
}
const numberStack = new Stack<number>();
numberStack.push(42); // 仅允许 number 类型

此类实现保证了栈内元素的类型一致性。

4. 类型别名的泛型写法

type 命令定义的类型别名,也可以使用泛型。

type Nullable<T> = T | undefined | null;

上面示例中,Nullable<T>是一个泛型,只要传入一个类型,就可以得到这个类型与undefinednull的一个联合类型。

三、高级泛型技巧

1. 泛型约束

通过 extends 限制类型参数的范围:

interface HasLength { length: number; }
function logLength<T extends HasLength>(arg: T): void {console.log(arg.length);
}
logLength("hello"); // 合法(length=5)
logLength(42);      // 错误:缺少 length 属性

此约束确保类型参数必须包含指定属性。

2. 多类型参数与默认值

多类型参数

function swap<T, U>(tuple: [T, U]): [U, T] {return [tuple[1], tuple[0]];
}
swap([7, "seven"]); // 返回 ["seven", 7]

但是类型参数越少越好,下面我会讲到

默认类型

class Generic<T = string> {list:T[] = []add(t:T) {this.list.push(t)}
}const g = new Generic();
g.add(4) // 报错
g.add('hello') // 正确-------------------------------------------const g = new Generic<number>();
g.add(4) // 正确
g.add('hello') // 报错

上面示例中,类Generic有一个类型参数T,默认值为string。这意味着,属性list默认是一个字符串数组,方法add()的默认参数是一个字符串。所以,向add()方法传入一个数值会报错,传入字符串就不会。反之,传入字符串会报错。

3. 索引类型与 keyof

确保对象属性访问的安全性:

function getValue<T, K extends keyof T>(obj: T, key: K): T[K] {return obj[key];
}
const person = { name: "Alice", age: 30 };
getValue(person, "name"); // 合法
getValue(person, "gender"); // 错误:属性不存在。

4. 条件类型与映射类型

条件类型:根据条件选择类型:

type Check<T> = T extends string ? "string" : "not string";
type A = Check<"hello">; // "string"

映射类型:基于已有类型生成新类型:

type Readonly<T> = { readonly [P in keyof T]: T[P] };
type ReadonlyPerson = Readonly<Person>; // 所有属性变为只读。

四、泛型的正确使用场景与注意点

1.正确使用场景

  • 当需要在多个位置(参数、返回值、成员变量)之间建立类型约束时。
  • 避免重复编写相似逻辑的类型特定代码(如不同数据类型的队列实现)。

2.注意点

1、尽量少用泛型。

泛型虽然灵活,但是会加大代码的复杂性,使其变得难读难写。一般来说,只要使用了泛型,类型声明通常都不太易读,容易写得很复杂。因此,可以不用泛型就不要用。

2、类型参数越少越好。

多一个类型参数,多一道替换步骤,加大复杂性。因此,类型参数越少越好。

function filter<T,Fn extends (arg:T) => boolean
>(arr:T[],func:Fn
): T[] {return arr.filter(func);
}

上面示例有两个类型参数,但是第二个类型参数 Fn 是不必要的,完全可以直接写在函数参数的类型声明里面。

function filter<T>(arr:T[],func:(arg:T) => boolean
): T[] {return arr.filter(func);
}

上面示例中,类型参数简化成了一个,效果与前一个示例是一样的。

3、类型参数需要出现两次。

如果类型参数在定义后只出现一次,那么很可能是不必要的。

function greet<Str extends string>(s:Str
) {console.log('Hello, ' + s);
}

上面示例中,类型参数Str只在函数声明中出现一次(除了它的定义部分),这往往表明这个类型参数是不必要。

function greet(s:string) {console.log('Hello, ' + s);
}

上面示例把前面的类型参数省略了,效果与前一个示例是一样的。

也就是说,只有当类型参数用到两次或两次以上,才是泛型的适用场合。

4、泛型可以嵌套。

类型参数可以是另一个泛型。

type OrNull<Type> = Type|null;
type OneOrMany<Type> = Type|Type[];
type OneOrManyOrNull<Type> = OrNull<OneOrMany<Type>>;

上面示例中,最后一行的泛型OrNull的类型参数,就是另一个泛型OneOrMany

五、实战应用案例

1. React 组件泛型

定义可接收多种 props 类型的组件:

interface ListProps<T> {items: T[];renderItem: (item: T) => React.ReactNode;
}
function List<T>({ items, renderItem }: ListProps<T>) {return <div>{items.map(renderItem)}</div>;
}
// 使用
<List<number> items={[1, 2]} renderItem={(n) => <div>{n}</div>} />。

2. API 请求封装

利用泛型约束返回数据类型:

async function fetchData<T>(url: string): Promise<T> {const response = await fetch(url);return response.json() as T;
}
interface User { id: number; name: string; }
const users = await fetchData<User[]>("/api/users");。
http://www.dtcms.com/wzjs/548321.html

相关文章:

  • 北京网站优化对策河南信阳网站建设公司电话
  • 网站商城支付宝开通怎么做成都app开发制作公司
  • 网站建设课程设计摘要百度提交网站入口网址
  • 学校网站建设作用unity3d培训班多少钱
  • 广州做网站技术常州承接网站建设
  • 网站开发管理制度产品效果图怎么做出来的
  • 江苏太平洋建设集团官方网站穆棱建设局网站
  • 做牙齿的招聘网站江西网络推广seo
  • 做网站怎样赚卖流量买软件网站建设
  • 做网站时如何建立栅格京津冀协同发展四区指的是
  • 网站建设技术是什么公司网上注册系统
  • 劳力士手表网站办公室装修费用分几年摊销
  • 龙川做网站的wordpress广告平台
  • 动地科技登录网站公司网站制作流程
  • 华仁建设网站wordpress中文案例
  • 网站建设html代码自建网站营销是什么
  • 济南网站建设q.479185700惠网络优化的流程
  • 惠州市建网站公司福州鼓楼区网站建设
  • 同一产品做多个网站小程序开发注意事项
  • 网站没内容可以备案吗重庆涪陵网站设计公司哪家专业
  • 建设通网站原理网页升级紧急通知书
  • 网站开发与推广就业太原做手机网站建设
  • 泾川县建设局网站新西兰网站开发专业
  • 做游戏直播什么游戏视频网站南宁网络营销策划推广公司
  • 肇庆网站建设咨询高端顺口公司名字
  • 网站开发语言总结做网站多少分辨率好
  • 企业如何做网站推广网站建设合同浩森宇特
  • 莱芜网站优化加徽信xiala5效果好wordpress修改文章固定id
  • 株洲做网站公司网站建设网站软件有哪些内容
  • 建设一个网站需要哪方面的费用北京十大活动策划公司