2016-10-21 18 views
3

JSONから指定された型のオブジェクトを返すために使用したいサービスがあります。Typescriptはジェネリック型の静的メソッドを呼び出す

私はクラスMyClassを持っています。これは、FromJSON静的メソッドを定義する静的クラスを実装しています。

export interface InterfaceMyClass { 
    static FromJSON(json: any): any; 
} 

export class MyClass implements InterfaceMyClass { 

    constructor(){} 

    FromJSON(json: any): MyClass { 
     let instance = MyClass.create(MyClass.prototype); 
     Object.assign(instance, json); 
     // Some other code specific to MyClass 
     return instance; 
    } 
} 

私のサービスでパラメータで渡したジェネリッククラスの静的メソッドを呼び出す方法がわかりません。 私のサービスは、次のようになります。

export class MyService<T extends InterfaceMyClass> { 
    getObject() { 
     let json = getExternalJson(...); 
     return T.FromJSON(json); // <-- How to call static method FromJSON from T class ? 
    } 
} 

私がサービスを使用するには、この方法をしたいと思います:

let service = new MyService<MyClass>(); 
let myObject = service.getObject(); // <-- Should by an MyClass instance (created by MyClass.FromJSON) 

質問:私はこのT.FromJSONメソッドを呼び出すことができますどのように ?

ボーナスに関する質問:どのような方法で静的メソッドを実装するのですか?私はMyClassの私のメソッドは静的だとは思わない。私はFromJSON前に静的な単語を追加する場合、それはこの私に語った:

[ts] Class 'MyClass' incorrectly implements interface 'InterfaceMyClass'. 
     Property 'FromJSON' is missing in type 'MyClass'. 

答えて

1

いくつかのこと:

は、(1)インタフェースは、例えば、静的な宣言を持つことはできません。

interface MyInterface { 
    static myMethod(); // Error: 'static' modifier cannot appear on a type member 
} 

を( code in playground

typescriptでこれを回避する方法は、ビルダー/コンストラクタインターフェイスを定義することです。

interface MyInterface {} 

interface MyInterfaceBuilder { 
    new(): MyInterface; 
    myMethod(); 
} 

(2)一般的な制約はコンパイル時にのみ使用可能ですが、JavaScriptがそれをサポートしていないと、コンパイラは、例えば、それらを削除します。

var MyClass = (function() { 
    function MyClass() { 
     this.member = new T(); // Error: Cannot find name 'T' 
    } 
    return MyClass; 
}()); 

class MyClass<T extends string> { 
    private member: T; 

    constructor() { 
     this.member = new T(); // Error: Cannot find name 'T' 
    } 
} 

はにコンパイルされます

code in playground

js出力を見ると、なぜコンパイラがをスローするのかはっきりしています。エラー、Tが見つかりませんでした。

interface IMyClass {} 

interface IMyClassBuilder<T extends IMyClass> { 
    new(): T; 
    FromJSON(json: any): any; 
} 

class MyClass implements IMyClass { 
    static FromJSON(json: any) { 
     return ""; 
    } 
} 

class MyService<T extends IMyClass> { 
    private classToCreate: IMyClassBuilder<T>; 

    constructor(classToCreate: IMyClassBuilder<T>) { 
     this.classToCreate = classToCreate; 
    } 

    getObject(): T { 
     let json = getExternalJson(...); 
     return this.classToCreate.FromJSON(json); 
    } 
} 

let service = new MyService(MyClass); 
let myObject = service.getObject(); 

code in playground

:そのすべてを回避する

は、ここにあなたのためのソリューションです

関連する問題