2016-04-27 17 views
12

Die Art Signatur für eine nicht-abstrakte Klasse (nicht abstrakte Konstruktor-Funktion) in Typoskript ist die folgende:Abstrakt Konstruktortyp in Typoskript

declare type ConstructorFunction = new (...args: any[]) => any; 

Dies auch ein newable Typ genannt wird. Allerdings brauche ich eine Typ-Signatur für eine abstrakte Klasse (abstrakte Konstruktorfunktion). Ich verstehe, dass es so definiert werden kann, mit dem Typ Function, aber das ist Weg zu breit. Gibt es keine präzisere Alternative?


Edit:

Um zu klären, was ich meine, zeigt der folgende kleine Schnipsel, den Unterschied zwischen einem abstrakten Konstruktor und einem nicht-abstrakten Konstruktor:

declare type ConstructorFunction = new (...args: any[]) => any; 

abstract class Utilities { 
    ... 
} 

var UtilityClass: ConstructorFunction = Utilities; // Error. 

Typ ' typeof Utilities 'ist nicht dem Typ' new '(... args: any []) => any' zuweisbar.

Ein abstrakter Konstruktortyp kann einem nicht abstrakten Konstruktortyp nicht zugewiesen werden.

+0

Können Sie das näher erläutern? Vielleicht mehr Code zur Verfügung stellen? Warum unterscheidet sich in diesem Fall zwischen abstrakten und nicht-abstrakten Klassen? Der ctor ist niemals abstrakt. –

+1

@NitzanTomer Ich schätze Ihre Hilfe. Ich habe ein [mcve] in die Frage bearbeitet, um das Problem zu demonstrieren. Grundsätzlich muss ich eine Klasse als Argument übergeben. Der Typ 'ConstructorFunction' funktioniert für nicht abstrakte Klassen, nicht jedoch für abstrakte Klassen. –

Antwort

12

war nur mit einem ähnlichen Problem zu kämpfen selbst, und diese scheint für mich zu arbeiten:

type Constructor<T> = Function & { prototype: T } 
+2

Was zum Teufel bedeutet das? Was ist diese seltsame Syntax ??? – cheez

+4

Danke, das macht genau das, was benötigt wird. @cheez - Dies beschreibt eine Funktion mit einem Prototyp. Anstatt zu definieren, dass der Typ einen Konstruktor definiert, definiert dies, dass der Prototyp definiert wird. Was eine abstrakte Klasse ist - kein Konstruktor, nur der Prototyp. –

+0

Perfekte Lösung, danke! – Pavel

0

Der springende Punkt mit abstrakten Klassen (in OO im Allgemeinen) ist, dass man sie nicht instanziiert können, müssen Sie eine konkrete nicht abstrakte Umsetzung.

Ich nehme an, dass Sie verschiedene Implementierungen zu dieser abstrakten Klasse haben und in der Lage sein wollen, eine dieser Implementierungen zu erhalten (als Parameter oder etwas Ähnliches).
Wenn das der Fall ist, dann vielleicht könnte dies Ihr Problem lösen:

declare type ConstructorFunction<T extends Utilities> = new (...args: any[]) => T; 

abstract class Utilities { } 

class MyUtilities extends Utilities { } 

var UtilityClass: ConstructorFunction<MyUtilities> = MyUtilities; 
+0

Leider habe ich _need_ eine abstrakte Klasse als Argument übergeben, was möglich ist, wenn der Parametertyp 'any' oder' Function' ist. Bei diesen Typen können jedoch auch andere Objekte als abstrakte Klassen übergeben werden, weshalb ich eine Typdefinition speziell für abstrakte Klassen benötige. –

+0

@JohnWhite Warum müssen Sie eine abstrakte Klasse bestehen? Das ist ein seltsames Szenario –

+0

Ja, ist es. Es ist für eine benutzerdefinierte Serialisierungs-/Deserialisierungs-Engine, bei der Eigenschaften mit Dekoratoren versehen werden können. Member polymorhpism wird unterstützt und daher kann für einen Eigenschaftstyp eine abstrakte Klasse angegeben werden, die dann in eine Metadatenstruktur übergeben wird. Aktuell sind Laufzeit-Typprüfungen vorhanden, aber mit Typ-Sicherheit wäre es deutlich besser. –

3

das gleiche Problem. Ich denke, eine Essenz der abstrakten Konstruktorsignatur ist ein von new (...) : X in seiner Deklaration. Deshalb kann es explizit deklariert werden.

Jedoch. Sie können dies tun, und es wird kompiliert.

var UtilityClass: typeof Utilities = Utilities; 

typeof Something ist eine schöne Art und Weise Konstruktor Typen zu verweisen, aber es kann nicht verlängert werden.

Und in jedem Fall, dass Sie etwas wie dies tun können:

var UtilityClass: ConstructorFunction = <any> Utilities;