2017-07-03 7 views
0

型付き関数を使用して混合配列から特定の型を取り出すことは可能ですか?typescript - 型付き関数を使用して混合配列から特定のクラスインスタンスを返します

public plugins: (Tool|Service)[] = []; 
getTools(): Tool[]{ 
    return this.plugins.filter(t => t instanceof Tool); 
} 

これまでのところ私には運がありません。活字体は、メッセージenter image description here

TS2322以下投げている:タイプ '(ツール|サービス)[]' 'ツール[]' を型に代入できません。タイプ 'サービス'に 'onclick'プロパティがありません。

機能タイプをTool[]に設定する方法はありますか。ここで

は完全なコードです:

interface Required { 
    id: string 
    title: string 
    owner: string 
    type: 'user' | 'admin' 
} 

class P { 
    id; title; owner; type; 
    constructor(config: Required){ 
     this.id = config.id || 'uniqid'; 
     this.title = config.title || 'Title'; 
     this.owner = config.owner || 'user'; 
     this.type = config.type; 
    } 
} 

interface ToolRequired extends Required{ 
    onclick:() => void 
} 

class Tool extends P { 
    onclick; 
    constructor(config = {} as ToolRequired){ 
     super(config); 
     this.type = 'tool'; 
     this.onclick = config.onclick 
    } 
} 

class Service extends P { 
    constructor(config = {} as Required){ 
     super(config); 
     this.type = 'service' 
    } 
} 

class Storag { 
    static types = { 
     tool: Tool, 
     service: Service, 
     undefined: Tool, 
    }; 
    public plugins: (Tool|Service)[] = []; 
    setPlugin(config = {} as Required){ 
     const Type = Storag.types[config.type]; 
     this.plugins.push(new Type(config)); 
    } 
    getTools(): Tool[]{ 
     return this.plugins.filter(t => t instanceof Tool); 
    } 
} 

答えて

1

だけで終わりにas Tool[]にタック。

public plugins: (Tool|Service)[] = []; 
getTools(): Tool[]{ 
    return this.plugins.filter(t => t instanceof Tool) as Tool[]; // << here 
} 

活字体のコンパイラは、あなたがそれをのみリターンToolの意志、このようなフィルタを行うときにことを知っているのに十分にスマートではありませんので、あなたがこれを行う必要がある理由があります。すべての配列の.filterとなります。通常は、前の配列と同じ型を返します。これは、コンパイラと仮定すると、Tool|Service配列になります。など、あなたがコンパイラI know what I'm doing - the type that ".filter" returns will only be Tools hereを伝えるために最後にas Tool[]を行うことができ、およびコンパイラが耳を傾け、尊重します -

コンパイラは、Tool|ServiceのみTool秒にまで低減することができる、しかし、知っているのに十分スマートですそのように。

asキーワードの詳細はhttps://www.typescriptlang.org/docs/handbook/basic-types.htmlです(スクロールダウンまたは「タイプアサーション」を検索してください)。

+0

はtypescriptを持っていません2.4これを許可しました - 推論ターゲットとして型を返します(https://blogs.msdn.microsoft.com/typescript/2017/06/27/announcing-typescript-2-4/を参照) –

+0

' Array.map'は間違いなく動作します: 'Array.filter'は次のようなことはしません:c(つまり、' plugins.map(a => a as a Tool) 'vs' plugins.filter(a => a instanceof Tool) ) –

+0

はい - あなたは正しいです。今すぐこれを試してみてください。 –

関連する問題