在TypeScript中扩展数组

Fra*_*pen 44 typescript

如何将方法添加到基类型,比如Array?在全球模块中,这将得到认可

interface Array {
   remove(o): Array;
}
Run Code Online (Sandbox Code Playgroud)

但在哪里放实际实施?

Fen*_*ton 76

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

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

Array.prototype.remove = function (o) {
    // code to remove "o"
    return this;
}
Run Code Online (Sandbox Code Playgroud)

如果您在一个模块中,则需要明确指出您是指整个模块Array<T>,而不是Array<T>在模块中创建本地接口:

declare global {
    interface Array<T> {
        remove(o: T): Array<T>;
    }
}
Run Code Online (Sandbox Code Playgroud)


Rik*_*son 43

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);
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 我根据您的问题在`this`参数中添加了显式类型。请参阅https://www.typescriptlang.org/docs/handbook/functions.html的“此参数”部分。 (2认同)

GAF*_*GAF 7

加入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);
  }
}
Run Code Online (Sandbox Code Playgroud)

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

  • @Saleh 使用 `import "./array_extensions"` (4认同)

Ale*_*lex 6

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

TypeScript有什么新功能:

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

类的extends子句以前需要指定类型引用.它现在接受一个表达式,可选地后跟一个类型参数列表.表达式的类型必须是构造函数函数类型,其中至少有一个构造签名,其类型参数的数量与extends子句中指定的类型参数的数量相同.匹配构造签名的返回类型是类实例类型继承的基类型.实际上,这允许在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());
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这会导致问题,因为 `[]` 运算符无法按预期运行。http://stackoverflow.com/questions/33947854/class-extended-from-built-in-array-in-typescript-1-6-2-does-not-update-length-wh (2认同)

Zuh*_*aha 6

延伸Array

这是一个扩展并向其Array添加方法的示例。remove这是一个 JavaScript 示例

/** @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]

Run Code Online (Sandbox Code Playgroud)

这是一个 TypeScript 示例。

我添加了一个构造函数并将其参数推送到数组中。(无法做到这一点super(...items)

class List<T> extends Array {
  constructor(...items: T[]) {
    super();
    this.push(...items);
  }

  public remove(item: T): T {
    const index = this.indexOf(item);
    if (index === -1) {
      throw new Error(`${item} not in list`);
    }
    this.splice(index, 1);
    return item;
  }
}
Run Code Online (Sandbox Code Playgroud)