77

基本型、たとえば配列にメソッドを追加するにはどうすればよいですか?グローバルモジュールでは、これが認識されます

interface Array {
   remove(o): Array;
}

しかし、実際の実装はどこに置くのでしょうか?

4

7 に答える 7

124

プロトタイプを使用して、アレイを拡張できます。

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>;
    }
}
于 2012-10-09T15:11:43.360 に答える
62

declare globalTypeScript2.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);
  }
}
于 2017-01-01T04:47:57.030 に答える
13

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エラーがない場合「グローバルスコープの拡張は、外部モジュールまたはアンビエントモジュール宣言に直接ネストすることしかできません。」

于 2018-03-28T11:48:18.920 に答える
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());
    }
}
于 2015-10-19T15:03:05.957 に答える
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");

これはtypescriptv2.2.1で動作します!

于 2017-03-27T15:14:21.143 に答える
3

拡張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]

そしてこれは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;
  }
}
于 2021-07-29T13:28:12.273 に答える
-1

同じことをして、マッピングを含むジェネリック関数を作成する必要がありました。

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などの特定のタイプを追加します。あなたが確かにあなたのタイプと取り替える必要があるもの。

于 2020-03-30T19:24:50.077 に答える