Gibt es eine Möglichkeit, Klassen in TypeScript zu verschachteln? ZB möchte ich sie verwenden wie:
var foo = new Foo();
var bar = new Foo.Bar();
Basarat
Gibt es eine Möglichkeit, Klassen in TypeScript zu verschachteln? ZB möchte ich sie verwenden wie:
var foo = new Foo();
var bar = new Foo.Bar();
Basarat
In modernem TypeScript gibt es Klassenausdrücke, mit denen Sie eine verschachtelte Klasse erstellen können. Sie können beispielsweise Folgendes tun:
class Foo {
static Bar = class {
}
}
// works!
var foo = new Foo();
var bar = new Foo.Bar();
Dieses Beispiel funktioniert nicht in Typescript 1.6.3: Fehler TS4028 Die öffentliche statische Eigenschaft „Bar“ der exportierten Klasse hat oder verwendet den privaten Namen „(anonyme Klasse)“.
– Sergej
23. Oktober 2015 um 12:23 Uhr
@Sergey Ich hatte das gleiche Problem, also fing ich an, Namespaces gemäß meiner Antwort unten zu verwenden.
– DanDef
29. September 2016 um 10:57 Uhr
Gibt es eine Möglichkeit, eine Schnittstelle innerhalb einer Klasse zu erstellen? dh wenn wir wollen, dass Bar eine Schnittstelle sein wird
– RoG
10. Oktober 2018 um 12:03 Uhr
@LittaHervi – Ein Anwendungsfall wäre die Rückgabe einer privaten Implementierung einer externen Schnittstelle, beispielsweise von einer Factory-Methode. Ein weiteres Beispiel aus Java (und anderen) sind Iteratoren, die privilegierten Zugriff auf Mitgliedsvariablen ihrer enthaltenden Klasse benötigen und dies durch Scoping-Regeln automatisch tun, aber Sie möchten nie, dass diese direkt exportiert und instanziiert werden.
– David
26. November 2019 um 5:57 Uhr
Gibt es eine Möglichkeit, die verschachtelte Klasse der übergeordneten Klasse wiederzuverwenden? Klasse Foo {statischer Balken = Klasse {}; FeldA: Balken; //funktioniert nicht: Name ‘Bar’ kann nicht gefunden werden fieldB: Foo.Bar; //funktioniert nicht: ‘Foo’ bezieht sich nur auf einen Typ, wird hier aber als Namensraum verwendet. } // funktioniert! var foo = neues Foo(); var bar = new Foo.Bar();
– LucasM
16. November 2021 um 16:01 Uhr
bnieland
Hier ist ein komplexerer Anwendungsfall mit Klasse Ausdrücke.
Es erlaubt die innere Klasse um auf die zuzugreifen private
Mitglieder von äußere Klasse.
class classX {
private y: number = 0;
public getY(): number { return this.y; }
public utilities = new class {
constructor(public superThis: classX) {
}
public testSetOuterPrivate(target: number) {
this.superThis.y = target;
}
}(this);
}
const x1: classX = new classX();
alert(x1.getY());
x1.utilities.testSetOuterPrivate(4);
alert(x1.getY());
@RyanCavanaugh Ist die Möglichkeit, auf private Mitglieder innerhalb eines “inneren” Klassenausdrucks zuzugreifen, ein Fehler?
– bnieland
25. Juli 2017 um 14:51 Uhr
Ich habe mit dem TypeScript-Team überprüft, ob dies die richtige Verwendung ist. github.com/Microsoft/TypeScript/issues/…
– bnieland
1. August 2017 um 0:34 Uhr
Ist es möglich, auf den übergeordneten Kontext zuzugreifen, ohne dies direkt zu übergeben?
– schabunc
11. Februar 2020 um 13:31 Uhr
@shabunc meines Wissens nicht
– bnieland
24. Juli 2020 um 3:02 Uhr
Idee Wenn Sie eine “echte” (nicht “statische”) innere Klasse (als Objektvorlage) benötigen, verwenden Sie sie wie () => new class
– PEZO
21. Mai 2021 um 12:13 Uhr
Dan Def
Ich konnte dies nicht mit exportierten Klassen zum Laufen bringen, ohne einen Kompilierungsfehler zu erhalten, stattdessen habe ich verwendet Namensräume:
namespace MyNamespace {
export class Foo { }
}
namespace MyNamespace.Foo {
export class Bar { }
}
Dasselbe. ‘Foo’ bezieht sich nur auf einen Typ, wird hier aber als Namensraum verwendet.
– Will Beason
10. September 2019 um 19:51 Uhr
Wenn Sie sich im Kontext einer Typdeklarationsdatei befinden, können Sie dies tun, indem Sie Klassen und Namespaces mischen:
// foo.d.ts
declare class Foo {
constructor();
fooMethod(): any;
}
declare namespace Foo {
class Bar {
constructor();
barMethod(): any;
}
}
// ...elsewhere
const foo = new Foo();
const bar = new Foo.Bar();
Warnio
Bei dieser Antwort geht es um a nahtlos verschachtelte Klassenimplementierung in TypeScript, das auf der Antwort von @basarat aufbaut.
Um den Typ des zu machen statisch verschachtelte Klasse Bar
zugänglich (wie @PeterMoore betonte), deklarieren Sie den Typ der verschachtelten Klasse in einem Namespace. Auf diese Weise können wir die Verknüpfung verwenden Foo.Bar
. Durch Verschieben von Typ typeof Foo.Bar.prototype
in einen Typ in einem deklarierten Namensraum, müssen wir den Ausdruck nicht wiederholen.
class Foo {
static Bar = class {
}
}
declare namespace Foo {
type Bar = typeof Foo.Bar.prototype
}
// Now we are able to use `Foo.Bar` as a type
let bar: Foo.Bar = new Foo.Bar()
Für statische Klassen könnte die folgende Implementierung eleganter sein. Dies funktioniert jedoch nicht mit nicht statischen Klassen.
class Foo { }
namespace Foo {
export class Bar { }
}
let bar: Foo.Bar = new Foo.Bar()
Um die Klasse zu exportieren, kann eine export-Anweisung hinzugefügt werden, nachdem die Klasse und der Namensraum deklariert wurden, z export default Foo
oder export { Foo }
.
Um dasselbe mit einer nicht statischen verschachtelten Klasse zu erreichen, sehen Sie sich das folgende Beispiel an.
class Foo { Bar = class { } } declare namespace Foo.prototype { type Bar = typeof Foo.prototype.Bar.prototype } let foo: Foo = new Foo() let bar: Foo.prototype.Bar = new foo.Bar()
Ich hoffe, das kann hilfreich sein
Fähig:
Anwendungsfall
export interface Constructor<T> {
new(...args: any[]): T;
}
export interface Testable {
test(): void;
}
export function LogClassName<T>() {
return function (target: Constructor<T>) {
console.log(target.name);
}
}
class OuterClass {
private _prop1: string;
constructor(prop1: string) {
this._prop1 = prop1;
}
private method1(): string {
return 'private outer method 1';
}
public InnerClass = (
() => {
const $outer = this;
@LogClassName()
class InnerClass implements Testable {
private readonly _$outer: typeof $outer;
constructor(public innerProp1: string) {
this._$outer = $outer;
}
public test(): void {
console.log('test()');
}
public outerPrivateProp1(): string {
return this._$outer._prop1;
}
public outerPrivateMethod1(): string {
return this._$outer.method1();
}
}
return InnerClass;
}
)();
}
const outer = new OuterClass('outer prop 1')
const inner = new outer.InnerClass('inner prop 1');
console.log(inner instanceof outer.InnerClass); // true
console.log(inner.innerProp1); // inner prop 1
console.log(inner.outerPrivateProp1()); // outer prop 1
console.log(inner.outerPrivateMethod1()); // private outer method 1
Für älteres Typoskript (<1.6) siehe Irgendeine Möglichkeit, Klassen in Typoskript zu verschachteln?
– Rahul Tripathi
10. September 2015 um 6:03 Uhr