泛型(Generics)是 TypeScript 中一个重要的概念,它允许你在编写可重用、灵活的函数、类或接口时,参数或返回值的类型变成一个占位符。
下面是一些关于 TypeScript 泛型的基本概念和用法:
-
函数泛型:
// 用 T K 限制某一类型 function xx<T, K>(x: T, y: K):Array<K |T> { return [x, y] } xx(1, false) // 会自动类型推断
也可以添加默认类型,例如 T = number
,此时默认为 number
,当然也还是可以使用其他类型。
-
接口泛型:
type A<T> = string | number | T let a: A<number> = 1 // 或者interface interface Data<T> { msg: T } let data: Data<number> = { msg: 1 }
这里我们创建了一个
Box
接口,它接受一个类型参数T
。当我们声明一个box
变量时,我们指定了泛型类型为number
,这意味着box
中的value
属性的类型将会是number
。 -
类泛型:
class Pair<T, U> { constructor(public first: T, public second: U) {} } let pair = new Pair<number, string>(1, "one");
这里我们创建了一个泛型类
Pair
,它可以接受两个类型参数T
和U
。在实例化时,我们指定了number
和string
作为类型参数,因此pair
对象的first
属性将是number
类型,而second
属性将是string
类型。 -
泛型约束:
function loggingIdentity<T extends Lengthable>(arg: T): T { console.log(arg.length); return arg; } interface Lengthable { length: number; } loggingIdentity("Hello"); // OK loggingIdentity(42); // Error: 无法找到 length 属性
这里的
Lengthable
接口约束了泛型类型必须有一个length
属性。函数loggingIdentity
接受一个类型为T
(必须符合Lengthable
接口的约束)的参数,并输出其length
属性。
应用场景:
const axios = {
get<T>(url: string): Promise<T> {
return new Promise<T>((resolve, reject) => {
let xhr: XMLHttpRequest = new XMLHttpRequest()
xhr.open('GET', url)
xhr.onreadystatechange = () => {
if(xhr.readyState == 4 && xhr.status == 200) {
resolve(JSON.parse(xhr.responseText))
}
}
xhr.send(null)
})
}
}
interface Data {
message:string,
code:number
}
axios.get<Data>('./data.json').then(res => {
console.log(res.code);
})
data.json
{
"messsage":"success"'./index.js'
"code": 1
}
将 index.ts 同步编译到 index.js ,在 index.html 中引入 ‘./index.js’