javascript - Kan du skapa inbäddade klasser i TypeScript?


Finns det ett sätt att nästla klasser i TypeScript. Till exempel, jag skulle vilja använda dem så här:

var foo = new Foo();
var bar = new Foo.Bar();

Svar #1

I modern TypeScript har vi klassexpressioner som du kan använda för att skapa en nästlad klass. Till exempel kan du göra följande:

class Foo {
    static Bar = class {
        
    }
}

// works!
var foo = new Foo();
var bar = new Foo.Bar();

Svar #2

Här är ett mer komplext användningsfall med klasstryckningar.

Det tillåter inre klassen att komma åt privata medlemmar i yttre klassen.

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());

codepen

Svar #3

Jag kunde inte få detta att fungera med exporterade klasser utan att få ett kompilatorfel, istället använde jag namnrymder:

namespace MyNamespace {
    export class Foo { }
}

namespace MyNamespace.Foo {
    export class Bar { }
}

Svar #4

Om du befinner dig i sammanhanget av en typsdefinitionsfil kan du göra detta genom att blanda klasser och namnrymder:

// 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();

Svar #5

Statisk nästling

Att definiera den statiska nästlade klassen Foo.Bar kan göras på följande två sätt.

  1. Alternativ 1: Implementera Bar inom namnrymden Foo.
    Typen deklareras automatiskt med deklarationssammanslagning.

    class Foo { }
    
    namespace Foo {
        export class Bar { }
    }
    
    let bar: Foo.Bar = new Foo.Bar()
    
  2. Alternativ 2: Implementera Bar inuti klassen Foo.
    Typen deklareras i en ambient namespace-deklaration.

    class Foo {
        static Bar = class { }
    }
    
    declare namespace Foo {
        type Bar = typeof Foo.Bar.prototype
    }
    
    let bar: Foo.Bar = new Foo.Bar()
    

Icke-statisk nästling

Att definiera den icke-statiska nästlade klassen Foo.prototype.Bar kan göras på följande sätt.
Typen deklareras återigen i en ambient namespace-deklaration.

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()

Observera: anropet new Foo.prototype.Bar() fungerar inte, även om det är giltig Typescript även utan typspecificering.

Relaterade artiklar