如何在 TypeScript 中为特定类型的泛型创建扩展方法

And*_*ray 6 generics extension-methods typescript

对于我正在从事的半教育副项目,我有一个 TypeScript interfaceid它在实现它的任何对象上公开一个变量。在这个应用程序中,有Array<>s 个这些IIdable对象是相当普遍的。

由于这个应用程序不使用数据库,我正在尝试做的事情是为服务实现一个自动增量器,以跟踪这些IIdables列表。自然地,我考虑添加一个“JavaScript”方式的扩展,如下所示......

Array<MyProject.Models.IIdable>.prototype.getNextId = () => {
    let biggestId: number = 0;
    for (let current of this) {
        if (current.id > biggestId)
            biggestId = current.id;
    }

    return biggestId + 1;
};
Run Code Online (Sandbox Code Playgroud)

...但是 Visual Studio Code 抛出了几个错误,其中一个是:

Cannot find name 'prototype'
Run Code Online (Sandbox Code Playgroud)

我觉得这是有问题的,因为Array<T>s 是 JavaScript 的“原始”,并且所有东西都是objectJavaScript 中的(因此,TypeScript 的一些问题是为了减少或完全避免而创建的。)但是,我意识到我对两者都了解得够多了JavaScript 和 TypeScript 是“危险的”,这意味着我知道的事情足够多,可以让自己做一些非常愚蠢的事情。

如果我使用的是 C# - TypeScript 不是 - 我会编写这样的扩展方法:

public static GetNextId(this List<IIdable> source)
{
    // ...Read each IIdable's ID to figure out the next biggest to give.
}
Run Code Online (Sandbox Code Playgroud)

...不幸的是,据我所知,我不能完全做到这一点。在发布此问题之前,我对在 TypeScript 中编写扩展方法进行了一些研究。一个这样的答案是使用新方法修改主机类型的接口,在这种情况下我不想这样做。我只想为我们处理 的情况添加扩展名Array<IIdable>,而不是其他人。

因此,我必须问: 我可以以什么方式在 TypeScript 中针对特定类型的事物在泛型类型上编写扩展方法?

Mat*_*hen 8

泛型类Array只有一个原型;访问原型时不能指定类型参数。但是,您可以覆盖this方法的类型。以下是您将如何声明然后定义方法。请注意,您必须使用function能够接收this参数的函数,而不是箭头函数,箭头函数始终使用this定义它的范围内的函数(在本例中为全局对象)。

interface Array<T> { 
  getNextId(this: MyProject.Models.IIdable[]): number;
}

// The `this` type for the function is taken from the declaration above.
Array.prototype.getNextId = function() {
    let biggestId: number = 0;
    for (let current of this) {
        if (current.id > biggestId)
            biggestId = current.id;
    }

    return biggestId + 1;
};
Run Code Online (Sandbox Code Playgroud)