web-dev-qa-db-ja.com

TypeScript:継承クラスの静的メソッドの自己参照型

TypeScript 1.7で Polymorphic this を使用すると、 here を発見したので、戻り値の型がthisのクラスにメソッドを定義でき、自動的に、そのクラスを拡張し、メソッドを継承するクラスは、戻り値の型をそれぞれのthis型に設定します。そのようです:

class Model {
  save():this {    // return type: Model
    // save the current instance and return it
  }
}

class SomeModel extends Model {
  // inherits the save() method - return type: SomeModel
}

ただし、私が求めているのは、継承されたstaticメソッドに、クラス自体を参照する戻り値の型を持たせることです。コードで最もよく説明されています:

class Model {
  static getAll():Model[] {
    // return all recorded instances of Model as an array
  }

  save():this {
    // save the current instance and return it
  }
}

class SomeModel extends Model {
  // inherits the save() method - return type: SomeModel
  // also inherits getAll() - return type: Model (how can we make that SomeModel?)
}

TypeScript 1.7の多態性thisstaticメソッドを設計でサポートしていないため、おそらくこれを実装する別の方法を考えなければならないでしょう(= /// =)

[〜#〜] edit [〜#〜]:このGithubの問題のまとめ: https:/ /github.com/Microsoft/TypeScript/issues/586

16
Merott

これはTypeScript 2.0以降で実行できます。インライン{ new(): T }タイプを使用してthisをキャプチャすることにより、必要なものが得られます。

class BaseModel {

  static getAll<T>(this: { new(): T }): T[] {
    return [] // dummy impl
  }

  save(): this {
    return this  // dummy impl
  }
}

class SubModel extends BaseModel {
}

const sub = new SubModel()
const savedSub: SubModel = sub.save()
const savedSubs: SubModel[] = SubModel.getAll()

getAllは、この型指定ではまだ引数を期待しないことに注意してください。

詳細については、 https://www.typescriptlang.org/docs/handbook/generics.html#using-class-types-in-generics および https:// stackoverflow。 com/a/45262288/1268016

23
mrm

GitHubの問題 に対する 最も単純な答え に基づいて、 InstanceType<> このように:

class Foo {
    static create<T extends typeof Foo>(this: T): InstanceType<T> {
        return new this() as InstanceType<T>
    }

    static getAll<T extends typeof Foo>(this: T): Array<InstanceType<T>> {
        return []
    }
}

class Bar extends Foo { }

const a = Bar.getAll() // typeof a is Bar[]
const b = Bar.create() // typeof b is Bar.

リンクされたGitHubの例から、説明のためにcreate関数を入れました。

1
Brian M. Hunt

この静的メソッドが継承されたサブクラスで何を返すことを期待していますか?これは次のようなものですか?

class A {
    private static _instances = new Array<A>();
    static instances(): A[] { return A._instances; }
    constructor() { A._instances.Push(this); }
}

class B extends A {

    static instances(): B[] { 
        return <B[]>(A.instances().filter(i => i instanceof B)); 
    }
    constructor() { super(); }; 
}

var a = new A();
var b = new B();

console.log(
     "A count: " + A.instances().length + 
    " B count: " + B.instances().length);

これにより、「Aカウント:2 Bカウント:1」が出力されます。または何を期待していますか?

0
Nypan