模仿 TypeScript 中的扩展方法

这是一个有趣的挑战。我正在阅读 TypeScript github 中的这个旧问题,以支持使用类似于 C# 的扩展方法。提出了两种主要方法,一种是添加语法糖来扩展经常不受欢迎的对象原型,另一种是重写调用站点(请参阅此处的缺点和优点)。


我在想也许我们可以用另一种方式来模拟在 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(...???)

  };

}

我认为这是一个有趣的挑战,您认为如何实现,以及如何推广它,或者您能想到更好的方法吗?


MYYA
浏览 175回答 2
2回答

不负相思意

function ext<T, E>(obj: T, extension: E) {&nbsp; &nbsp;return (receiver: (extended: T & E) => any) => {&nbsp; &nbsp; &nbsp; receiver(new Proxy(obj, {&nbsp; &nbsp; &nbsp; &nbsp; get(target, prop, receiver) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(prop in extension)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return extension[prop];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return Reflect.get(...arguments);&nbsp; &nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; &nbsp; &nbsp; // TODO has, set, etc. according to needs&nbsp; &nbsp; &nbsp; } as T & E));&nbsp; &nbsp;};}ext(a, { includesAnyOf })(a => {&nbsp;a.includesAnyOf("stuff");});任务完成。function ext(obj, extension) {&nbsp; &nbsp; &nbsp; &nbsp;return (receiver) => {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; receiver(new Proxy(obj, {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; get(target, prop, receiver) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(prop in extension)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return extension[prop];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return Reflect.get(...arguments);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // TODO has, set, etc. according to needs&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }));&nbsp; &nbsp; &nbsp; &nbsp;};&nbsp; &nbsp; }&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;function includesAnyOf(...searchElements) {&nbsp; return searchElements.some(_ => this.includes(_));}&nbsp; &nbsp;&nbsp;const a = [1, 2, 3];ext(a, { includesAnyOf })(a => {&nbsp; console.log(a.includesAnyOf("stuff"));});你能想到更好的方法吗?老实说,我没有看到比常规功能有任何好处。在 C# 和其他语言中,它很有用,因为您可以使用自动完成功能轻松找到这些扩展。无论您如何在 TS 中执行此操作,都无法达到该目的。

慕工程0101907

我发现这样做的最简单方法是使用lodash.partial进行currying。function includesAnyOf<T>(array: T[], ...searchElements: T[]) {&nbsp; return searchElements.some(_ => array.includes(_));}import { partial } from 'lodash';const a = [1, 2, 3];const b = 3;const ext = (o) => {&nbsp; return {&nbsp; &nbsp; includesAnyOf: partial(includesAnyOf, o)&nbsp; };};console.log(&nbsp; ext(a).includesAnyOf(b) // true);
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript