在TypeScript中扩展数组

时间:2012-10-09 14:33:23

标签: typescript

如何将方法添加到基类型,比如说Array?在全局模块中,这将被识别

interface Array {
   remove(o): Array;
}

但是在哪里放置实际的实现?

7 个答案:

答案 0 :(得分:56)

您可以使用原型来扩展Array:

interface Array<T> {
    remove(o: T): Array<T>;
}

Array.prototype.remove = function (o) {
    // code to remove "o"
    return this;
}

如果您在某个模块中,则需要明确指出全局Array<T>,而不是在模块中创建本地Array<T>界面:

declare global {
    interface Array<T> {
        remove(o: T): Array<T>;
    }
}

答案 1 :(得分:37)

declare global似乎是TypeScript 2.1中的票证。请注意Array.prototype的类型为any[],因此如果您希望检查函数实现的一致性,最好自己添加泛型类型参数。

declare global {
  interface Array<T> {
    remove(elem: T): Array<T>;
  }
}

if (!Array.prototype.remove) {
  Array.prototype.remove = function<T>(this: T[], elem: T): T[] {
    return this.filter(e => e !== elem);
  }
}

答案 2 :(得分:7)

从TypeScript 1.6开始,您可以“本地”扩展任意表达式,如内置类型。

What's new in TypeScript

  

TypeScript 1.6增加了对扩展任意表达式的类的支持   计算构造函数。这意味着内置类型   现在可以在类声明中扩展。

     

类的extends子句以前需要类型引用   被指定。它现在接受一个表达式,可选地后跟一个   类型参数列表。表达式的类型必须是构造函数   具有至少一个具有相同构造签名的函数类型   type参数的数量,作为指定的类型参数的数量   extends子句。匹配构造的返回类型   signature(s)是类实例类型的基类型   继承。实际上,这允许真正的类和“类似”   要在extends子句中指定的表达式。

// Extend built-in types

class MyArray extends Array<number> { }
class MyError extends Error { }

// Extend computed base class

class ThingA {
    getGreeting() { return "Hello from A"; }
}

class ThingB {
    getGreeting() { return "Hello from B"; }
}

interface Greeter {
    getGreeting(): string;
}

interface GreeterConstructor {
    new (): Greeter;
}

function getGreeterBase(): GreeterConstructor {
    return Math.random() >= 0.5 ? ThingA : ThingB;
}

class Test extends getGreeterBase() {
    sayHello() {
        console.log(this.getGreeting());
    }
}

答案 3 :(得分:5)

加入Rikki Gibson的回答,

export{}
declare global {
    interface Array<T> {
        remove(elem: T): Array<T>;
    }
}

if (!Array.prototype.remove) {
  Array.prototype.remove = function<T>(elem: T): T[] {
      return this.filter(e => e !== elem);
  }
}

没有export {} TS错误“全局范围的扩充只能直接嵌套在外部模块或环境模块声明中。”

答案 4 :(得分:3)

class MyArray<T> extends Array<T> {
    remove: (elem: T) => Array<T> = function(elem: T) {
        return this.filter(e => e !== elem);
    }
}
let myArr = new MyArray<string>();
myArr.remove("some");

这适用于我的打字稿v2.2.1!

答案 5 :(得分:1)

扩展Array

这是一个扩展 Array 并向其添加 remove 方法的示例。 它是 JavaScript 并且肯定适用于 TypeScript

/** @template T */
class List extends Array {
  /**
   * Remove an item from the list and return the removed item
   * @param {T} item
   * @return {T}
   */
  remove(item) {
    const index = this.indexOf(item);
    if (index === -1) {
      throw new Error(`${item} not in list`);
    }
    this.splice(index, 1);
    return item;
  }
}

const arr = new List(1, 2, 3);
console.log(arr.remove(3)); // 3
console.log(arr); // [1, 2]

答案 6 :(得分:0)

我只需要这样做,并创建了一个包含映射的通用函数。

getDistinctValuesFromArray<T,R>(array: T[], mapping: (values: T) => R): R[] {
    return Array.from([...new Set(array.map(mapping))]);
}

您可以这样称呼它: getDistinctValuesFromArray<ArrayType, ElementType>(yourArray, a => a.elem) 具体来说,我喜欢添加特定类型,例如ArrayType和ElementType。您肯定需要用您的类型替换的那些。