web-dev-qa-db-ja.com

タイプスクリプトのクラスコンストラクタタイプ?

オブジェクトが一般クラスのコンストラクターであることを確認するために、どのようにしてclass型を宣言できますか?

次の例では、AnimalClassまたはPenguinのいずれかになるように、どのタイプをLionに指定する必要があるかを知りたいです。

class Animal {
    constructor() {
        console.log("Animal");
    }
}

class Penguin extends Animal {
    constructor() {
        super();
        console.log("Penguin");
    }
}

class Lion extends Animal {
    constructor() {
        super();
        console.log("Lion");
    }
}

class Zoo {
    AnimalClass: class // AnimalClass could be 'Lion' or 'Penguin'

    constructor(AnimalClass: class) {
        this.AnimalClass = AnimalClass
        let Hector = new AnimalClass();
    }
}

もちろん、classタイプは機能せず、とにかく一般的すぎます。

49
arthur.sw

これがTypeScriptで最初に質問されたときに可能かどうかはわかりませんが、私の推奨する解決策はgenericsを使用することです:

class Zoo<T extends Animal> {
    constructor(public readonly AnimalClass: new () => T) {
    }
}

このように、変数penguinおよびlionは、TypeScriptインテリセンスでも具象型PenguinまたはLionを推測します。

const penguinZoo = new Zoo(Penguin);
const penguin = new penguinZoo.AnimalClass(); // `penguin` is of `Penguin` type.

const lionZoo = new Zoo(Lion);
const lion = new lionZoo.AnimalClass(); // `lion` is `Lion` type.
1
Nenad

TypeScriptインターフェイスリファレンス からのソリューション:

interface ClockConstructor {
    new (hour: number, minute: number): ClockInterface;
}
interface ClockInterface {
    tick();
}

function createClock(ctor: ClockConstructor, hour: number, minute: number): ClockInterface {
    return new ctor(hour, minute);
}

class DigitalClock implements ClockInterface {
    constructor(h: number, m: number) { }
    tick() {
        console.log("beep beep");
    }
}
class AnalogClock implements ClockInterface {
    constructor(h: number, m: number) { }
    tick() {
        console.log("tick tock");
    }
}

let digital = createClock(DigitalClock, 12, 17);
let analog = createClock(AnalogClock, 7, 32);

したがって、前の例は次のようになります。

interface AnimalConstructor {
    new (): Animal;
}

class Animal {
    constructor() {
        console.log("Animal");
    }
}

class Penguin extends Animal {
    constructor() {
        super();
        console.log("Penguin");
    }
}

class Lion extends Animal {
    constructor() {
        super();
        console.log("Lion");
    }
}

class Zoo {
    AnimalClass: AnimalConstructor // AnimalClass can be 'Lion' or 'Penguin'

    constructor(AnimalClass: AnimalConstructor) {
        this.AnimalClass = AnimalClass
        let Hector = new AnimalClass();
    }
}
50
arthur.sw

そのように:

class Zoo {
    AnimalClass: typeof Animal;

    constructor(AnimalClass: typeof Animal ) {
        this.AnimalClass = AnimalClass
        let Hector = new AnimalClass();
    }
}

あるいは単に:

class Zoo {
    constructor(public AnimalClass: typeof Animal ) {
        let Hector = new AnimalClass();
    }
}

typeof Classは、クラスコンストラクターの型です。静的クラスメンバーを適切に処理するため、カスタムコンストラクター型宣言よりも望ましい方法です。

TypeScript docs の関連部分は次のとおりです。 typeofを検索します。 TypeScriptの型注釈の一部として、この例ではクラスコンストラクター関数の型である「Animalというシンボルの型を指定してください」という意味です。

12
gaperton

オブジェクトが一般クラスのコンストラクターであることを確認するために、クラスタイプを宣言するにはどうすればよいですか?

コンストラクター型は次のように定義できます。

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

 class A { ... }

 function factory(Ctor: AConstructorTypeOf<A>){
   return new Ctor();
 }

const aInstance = factory(A);
1
AleC