generics - typescript 可以使用使用元素类型参数的方法扩展 Array.prototype 吗?

标签 generics typescript prototype

这是一个很长的标题来描述一些非常简单的事情。

interface Array<T> {
  sortBy<T, K>(keyFunction: (t: T) => K): T[];
}

.

export namespace util {
export function sortBy<Element, Key>(array: Element[], keyFunction: (t: Element) => Key ): Element[] {

    var arrayCopy = array.slice();

    var mapped = arrayCopy.map(function(el, i) {
      return { index: i, value: keyFunction(el) };
    });

    mapped.sort(function(a, b) {
      return +(a.value > b.value) || +(a.value === b.value) - 1;
    });

    for (let i = 0; i < array.length; i++) {
        let indexed = mapped[i];
        array[i] = arrayCopy[indexed.index];
    }

    var result = mapped.map(function(el){
      return arrayCopy[el.index];
    });

    return array;

}
}

.

Array.prototype.sortBy = function(keyFunction)  {return util.sortBy(this, keyFunction)}

我在这里实现了一些来自 MDN 的示例代码,以按数组键而不是比较函数进行排序,并尝试用它来修补数组原型(prototype)(关于这是否是一个好主意的评论是预期的)。

但是,当我调用它时,Typescript 无法验证 keyfunction 的正确参数类型,因此需要强制转换以防止编译器错误:

it('should sort in-place', () => {
    var list = [{a: 'z', i: 2}, {a: 'x', i: 0}, {a: 'y', i:1}];
    // all good
    list.sortBy(<Function>(obj) => obj.i);
    expect(list.map((obj) => obj.a)
               .join('')
    ).toBe('xyz');
})


it('should sort in-place', () => {
    var list = [{a: 'z', i: 2}, {a: 'x', i: 0}, {a: 'y', i:1}];
    // Error TS2339: Property 'i' does not exist on type '{}'
    list.sortBy((obj) => obj.i);
    expect(list.map((obj) => obj.a)
               .join('')
    ).toBe('xyz');
})

有什么方法可以更改此定义使其生效吗?有趣的是,调用 util.sortBy(array, function)(即作为函数,而不是方法)的类型参数可以正常工作。

最佳答案

您的接口(interface)声明的排序函数正在创建一个新的 T ( sortBy<T, K> ) 与 Array 断开连接的 T .应该是sortBy<K>并重复使用 ArrayT .

正确声明

interface Array<T> {
  sortBy<K>(keyFunction: (t: T) => K): T[];
}

var list = [{a: 'z', i: 2}, {a: 'x', i: 0}, {a: 'y', i:1}];

// Okay
list.sortBy((obj) => obj.i);

关于generics - typescript 可以使用使用元素类型参数的方法扩展 Array.prototype 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39323238/

相关文章:

javascript - 向原型(prototype)添加函数与对象字面量(使用 this)

javascript - 为什么 Object.create() 和 new Object() 计算出不同的原型(prototype)?

javascript - 将格式添加到 native 日期解析器

java - 条目集上的通用迭代器

java - 的意思 ?在 Map<String, ?>

javascript - 如何使用 typescript 中的函数从firestore获取文档?

typescript - Cypress 断言文本,同时忽略软连字符

javascript - 使用 JSDoc 时 Visual Studio Code 中的注释突出显示

java - 泛型类型和通配符类型的区别

java - 在泛型类中声明静态泛型变量