2017-12-15 16 views
1

他のJS開発者と同様に、私は、TypeScriptコンパイラが理解できる静的な方法で物事を書くことについて幾分新しく考えました。私の基本的なユースケースは、RESTエンドポイントにアクセスするためのジェネリッククラスで利用可能なアクションをカスタマイズすることです。私は、コンストラクタの引数に基づいて基本クラスにメソッド/小道具を動的に追加できますが、動的に(わかりやすく)intellisenseを間違ったものにしています。私はちょうどこの間違ったことを考えていることを知っています、そして、私が欲しいものを達成するための別のパラダイムがあります。コンパイラが理解できるように、どのようにして子クラスからベースクラスをカスタマイズできますか?ベースクラスのメソッド/小道具を条件付きで指定する

class Endpoint<T> { 
    constructor(
     methods: Array<'GET' | 'CREATE'> 
    ) { 
     // Conditionally add methods to the endpoint based on what was passed in 
     if (methods.includes('GET')) { 
      this.get = function get(id: string): Promise<T> { 
       return new Promise<T>(resolve => resolve()); 
      }; 
     } 
     if (methods.includes('CREATE')) { 
      this.create = function create(body: T): Promise<T> { 
       return new Promise<T>(resolve => resolve()); 
      }; 
     } 
    } 

    public get?: (id: string) => Promise<T>; 
    public create?: (body: T) => Promise<T>; 
} 

class User extends Endpoint<IUser> { 
    constructor() { 
     super(['GET']); 
    } 
} 

let u = new User(); 
// u.create will get transpiled away, but still shows up in intellisense 
+2

あなたは一種の抽象的な親クラスを実装しようとしていますか?次に、必要な基底クラスを定義し、そこから拡張されたクラスの必要な実装のための追加のインタフェースを提供するのはなぜですか? – Icepickle

+0

私は私が従うかどうかわからない。 'class User extends Endpoint はIGettable 'を実装しています。 –

+0

あるいは 'let u =新しいユーザー()をIGettable 'としますか?インスタンスの機能の共通部分として 'IGetCreate 'のような拡張インターフェースを定義していますか?それはうまくいくようです。 –

答えて

1

をあなたはこのコードを短縮することができるかもしれないし、それはかなりありませんが、基本的な考え方は、活字体2.2で導入されたmixinsを使用することです::

ここ

は私がしようとしているものです

class Endpoint<T> { 
} 

type Constructor<T> = new(...args: any[]) => T; 

function Gettable<T, U extends Constructor<Endpoint<T>> = typeof Endpoint>(Base: U) { 
    return class extends Base { 
     get(id: string): Promise<T> { 
      return new Promise<T>(resolve => resolve()); 
     } 
    } 
} 

function Createable<T, U extends Constructor<Endpoint<T>> = typeof Endpoint>(Base: U) { 
    return class extends Base { 
     create(body: T): Promise<T> { 
      return new Promise<T>(resolve => resolve()); 
     } 
    } 
} 

class User extends Gettable<IUser>(Endpoint)<IUser> { 
} 

const u = new User(); 
u.get("id"); // ok 
u.create(); // error, method doesn't exist