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

时间:2018-10-16 21:13:08

标签: typescript generics extension-methods

对于我正在从事的半教育性副项目,我有一个TypeScript interface,它在实现它的任何对象上公开了一个id变量。在此应用中,Array<>个对象中有IIdable个是相当普遍的。

由于该应用程序不使用数据库,我正在尝试执行的操作是对服务执行自动递增,以跟踪IIdable的这些列表。自然,我考虑过以如下“ 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;
};

...但是Visual Studio Code引发了两个错误,其中一个是:

Cannot find name 'prototype'

考虑到Array<T>是JavaScript的“原始”元素,并且考虑到一切都是JavaScript中的object,因此我认为这很可疑(因此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.
}

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

因此,我必须问:在TypeScript中,对于特定类型的东西,我可以用哪种方法在通用类型上编写扩展方法?

1 个答案:

答案 0 :(得分:2)

通用类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;
};