2017-04-03 11 views
1

このコードの失敗原因は何ですか?Typescriptのインターフェイスでのクラスレベルの汎用制約

interface ISomeData { 
    name: string; 
} 

class SomeData implements ISomeData { 
    name: string = "adam"; 
} 

class SomeClass<T extends ISomeData> { 
    constructor(dataTemplate?: T) { 
     this.dataTemplateInternal = dataTemplate; 
    } 

    private dataTemplateInternal: T; 

    public initSomeData() : T { 
     let data: T = new SomeData(); 
     if (this.dataTemplateInternal) { 
      return this.dataTemplateInternal; 
     } 
     return data; 
    } 
} 

「initSomeData」の最初の行は

タイプというエラー「を有しsomeDataが」「T」

を型に代入できません。しかし、私の一般的な制約はに基づいているので、 SomeDataが実装しているインタフェースで十分ではありませんか?

Ridiculously long link to this code in the TypeScript Playground

答えて

2

あなたがしたい場合は、次の

let data: ISomeData = new SomeData(); 

あなたはこのエラーを取得していないだろうが、TISomeDataではない、それは例えば、それはすることができ、ISomeDataより何か「もっと」です:

interface IMoreData extends ISomeData { 
    username: string; 
} 

そして、あなたはそれを言う:

let data: IMoreData = new SomeData(); 

usernameプロパティが不足しているため、正しくありません。
あなたは何をやっている知っているコンパイラ(AKAキャストを)伝えることでこの問題を解決することができます

let data: T = new SomeData() as T; 

それとも:

let data = new SomeData() as T; 
+0

はそれがあったこと、ありがとうございます!私はちょうど私がそれを試していない理由を確認する必要があると思ってちょっと考えていた! –

+0

ちょっとした疑問のように、「あなたの実装は(私の場合は 'interface ISomeData {name:string}')最低限でなければならないという制約ではなく、そのインタフェースを実装していないそれは "名前:文字列"を持っていますか?私はまだそれが暗黙のうちに私の意図を理解していない理由を理解していません。これは設計上のものか、言語仕様の "todo"のようなものですか? :)それにもかかわらず、あなたは、ロック、ありがとう! –

+1

ええ、ジェネリック制約は 'name'が' T'に存在することを保証しますが、** 'T' **は**' ISomeData'ではないので、コンパイラはあなたに警告します。インスタンスが 'SomeClass 'の場合、 'initSomeData'の結果は' ISomeData'ではなく 'IMoreData'タイプでなければなりません –

関連する問題