本文内容如下
泛型接口 + 泛型函数,泛型工厂函数
如果你都有了答案,可以忽略本文章,或去TS学习地图寻找更多答案
简单知识
// 类
class CommercialBank {
static count: number
constructor(public name: string, public money: number) { }
}
//双重性质:
1. 当做 类构造函数对象变量 使用
CommercialBank.count
2. 当做 创建类对象的类型 使用
let c = new CommercialBank('农业银行')
工厂函数
// 通用工厂函数类型
type constructorType = new (...arg: any) => any
// 工厂函数
function createInstanceFactory(Constructor: constructorType) {
console.log(Constructor.name)
return new Constructor('工商银行')
}
let result = createInstanceFactory(CommercialBank)
console.log(result); //result是any类型,无法读取属性
泛型工厂函数
createInstanceFactory调用时,传递CommercialBank泛型给constructorType,constructorType最终返回CommercialBank类型
// 通用工厂函数类型,接收泛型,返回泛型
type constructorReturnType<T> = new (...arg: any) => T
// 工厂函数
function createInstanceFactory<T>(Constructor: constructorReturnType<T>) {
console.log(Constructor.name) //CommercialBank
return new Constructor('工商银行')
}
// <CommercialBank> 当做类型使用,(CommercialBank) 当做对象变量使用
let result = createInstanceFactory<CommercialBank>(CommercialBank)
console.log(result.name); //result是CommercialBank类型,可以读取实例属性
该版本问题,参数写死
泛型工厂函数,附带参数
class CommercialBank {
static count: number
constructor(public name: string, public money: number) { }
}
type constructorReturnType<T> = new (...arg: any) => T
function createInstanceFactory<T>(Constructor: constructorReturnType<T>, ...Parameter: any[]) {
return new Constructor(...Parameter)
}
// function createInstanceFactory<CommercialBank>(Constructor: constructorReturnType<CommercialBank>, ...Parameter: any[]): CommercialBank
let result = createInstanceFactory(CommercialBank, '工商银行', 10000, 888) //问题:参数随便传,不会报错,也没有限制
泛型工厂函数,附带参数,最终版本
前提知识: 了解infer,用于获取参数,不会点击跳转
class CommercialBank {
static count: number
constructor(public name: string, public money: number) { }
}
type constructorType = new (...arg: any) => any
type constructorReturnType<T> = new (...arg: any) => T
type constructorParameterType<T extends constructorType> = T extends new (...arg: infer P) => any ? P : never
// 获取参数,两者等价
let constructorParameters: constructorParameterType<typeof CommercialBank> //[name: string, money: number]
let constructorParameters2: constructorParameterType<new (name: string, money: number) => CommercialBank> //[name: string, money: number]
function createInstanceFactory<T, P extends constructorType>(Constructor: constructorReturnType<T>, ...Parameter: constructorParameterType<P>) {
return new Constructor(...Parameter)
}
//function createInstanceFactory<CommercialBank, typeof CommercialBank>(Constructor: constructorReturnType<CommercialBank>, name: string, money: number): CommercialBank
let result = createInstanceFactory<CommercialBank, typeof CommercialBank>(CommercialBank, '工商银行', 10000) //限定参数,有提示
console.log(result);
语句详解
type constructorParameterType<T extends constructorType> = T extends new (...arg: infer P) => any ? P : never
<T extends constructorType>
泛型约束:限定只能传递构造函数类型的泛型
T extends new (...arg: infer P) => any ? P : never
传递的泛型 是否和 new (...arg: infer P) => any 相符合? 如果符合,返回P
( P就是infer 从构造函数中获取的参数 ), 如果不符合,返回never
在这个例子中,使用时传递的泛型是 typeof CommercialBank,它和new (...arg: infer P) => any 是符合的,所以拿到参数: [name: string, money: number]
学习更多