【发布时间】:2019-12-24 23:28:59
【问题描述】:
这是一个有趣的挑战。我正在阅读 TypeScript github 中的这个旧问题到 support Extension Methods,其用法类似于 C#。提出了两种主要的方法,一种是添加语法糖来扩展通常不受欢迎的对象原型,另一种是重写调用站点(参见优缺点here)。
我在想也许我们可以用另一种方式来模仿也适用于 JavaScript 的扩展方法。
假设我们有以下函数:
function includesAnyOf<T>(array: T[], ...searchElements: T[]) {
return searchElements.some(_ => array.includes(_));
}
// example:
const a = [1, 2, 3];
const b = 3;
includesAnyOf(a, b); // true
// as extension method it would look like:
// a.includesAnyOf(b);
现在我想实现函数ext,这样我就可以做到:
ext(a).includesAnyOf(b)
罢工>
ext(a)(_ => _.includesAnyOf(b));
保留参数的所有类型。我想知道这是否可能,但我从这个开始,不知道如何完成它!
function ext(obj: any) {
return {
includesAnyOf: (...args: any[]) => includesAnyOf(...???)
};
}
我认为这是一个有趣的挑战,您认为这可以如何实现,如何概括它,或者您能想到更好的方法吗?
【问题讨论】:
-
您可能对管道运营商github.com/tc39/proposal-pipeline-operator 感兴趣 - 不过它仍处于早期阶段。
-
哇,好强大!感谢分享!
-
我不确定您为什么希望
ext(a)成为函数而不是扩展对象。也就是说,你为什么要做ext(a)(x => x.includesAnyOf(1))而不仅仅是(ext(a)).includesAnyOf(1)? -
顺便说一句,我认为这里的一个令人困惑的问题是,即使使用recent improvements,您也需要比 TS 能够轻松处理的更高阶类型。如果
includesAnyOf专门只处理具体类型number[],您可能会使用通用扩展函数获得良好的强类型。但由于您可能希望它支持泛型T的T[],这是更高阶的,您可能会在其中看到unknown[]或其他过早解析的泛型。 -
@jcalz 回答你的第一个问题,我可能想多了!我基本上是在寻找最接近
a.includesAnyOf(b)语法的路径,而无需扩展对象原型或克隆数组。所以如果我们能做到ext(a).includesAnyOf(b)那就更好了。
标签: javascript typescript extension-methods