typescript - 这是不恰当使用泛型的案例吗?
问题描述
我试图弄清楚泛型的一种有趣用法的目的:
让我们以这个类为例:
class Person {
constructor(public personName: string) { }
setName(name: string) {
this.personName = name
}
}
这个装饰器:
export function logger<T extends any[]>(message: string | ((...msgArgs: T) => string)) {
return (_target: object, _propertyKey: string, propDesc: PropertyDescriptor) => {
const classMethod = propDesc.value;
propDesc.value = function (...args: T) {
const logMsg: string = typeof message === 'function' ? message.apply(this, args) : message;
console.log(logMsg)
const result = classMethod.call(this, ...args);
return result;
};
return propDesc;
};
}
我们可以这样使用它:
@logger("Setting name")
setName(name: string) {
this.personName = name
}
或者
@logger((nameParam)=> `Setting name ${nameParam}`)
setName(name: string) {
this.personName = name
}
按预期工作。但是我不明白为什么这应该是通用的:
logger<T extends any[]>
是的,它使我们能够使用T
而不是any[]
在多个地方使用。但看起来这只是一个棘手的解决方法和滥用通用语法。基本上这个泛型与泛型无关......甚至最糟糕的是装饰器propDesc.value = function
和参数函数| ((...msgArgs: T) => string)
共享相同的类型,即使它们没有任何共同之处。
我仍然觉得我在上面的陈述中可能是错误的。所以我想知道在这种特殊情况下是否有任何理由使用泛型来支持any[]
或type anyArg = any[]
ps 我有一种强烈的感觉,实现是受这篇文章的启发
解决方案
在这种情况下T
,仅用于键入rest
运算符。
而且,你是对的,没有意义使用T extends any[]
,因为我们可以用下一种方式:
export function logger<T,>(message: string | ((...msgArgs: T[]) => string)) {
return (_target: object, _propertyKey: string, propDesc: PropertyDescriptor) => {
const classMethod = propDesc.value;
propDesc.value = function (...args: T[]) {
const logMsg: string = typeof message === 'function' ? message.apply(this, args) : message;
console.log(logMsg)
const result = classMethod.call(this, ...args);
return result;
};
return propDesc;
};
}
考虑下一个例子:
export function logger<T,>(message: string | ((...msgArgs: T[]) => string)) {
}
logger((...args: string[]) => 'bar')
请将鼠标悬停在logger((...args: string[]) => 'bar')
您应该看到,T
泛型被推断为 string :
function logger<string>(message: string | ((...msgArgs: string[]) => string)): void
等等,如果我摆脱这个泛型怎么办?
export function logger(message: string | ((...msgArgs: unknown[]) => string)) {
}
logger((...args:number[])=>'foo') // error
我不再能够输入args
数组。
推荐阅读
- compiler-construction - 使用 Bison 编写解析器时的冲突
- spring - Spring数据休息,关系属性的默认值
- sql - What is the difference between LIKE '[A-D]%' ; and BETWEEN 'A' AND 'D' ; in SQL Server
- angular - 在 Angular 6 中重用组件 html
- vba - 如何创建一个内置用户表单的excel
- python - 如何在 Python 的哈希表中实现动态哈希?
- java - 无法通过套接字在android中的图像视图上显示图像
- spring-boot - MockMVC 测试如何验证答案
- android - RecyclerView 与 cursor Adapter 的实现
- r - R根据多行删除计数最少的行