javascript - Možete li stvoriti ugniježdene klase u TypeScriptu?


Postoji li način za ugnježđivanje klasa u TypeScriptu. Npr. želio bih ih koristiti ovako:

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

Odgovor #1

U modernom TypeScriptu imamo izraze klase koje možete koristiti za stvaranje ugniježdene klase. Na primjer, možete učiniti sljedeće:

class Foo {
    static Bar = class {
        
    }
}

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

Odgovor #2

Evo složenijeg primjera korištenja izraza klasa.

Omogućuje unutarnjoj klasi pristup privatnim članovima vanjske klase.

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

Odgovor #3

Nisam uspio ovo napraviti s izvezenim klasama bez da dobijem grešku pri kompilaciji, umjesto toga koristio sam prostore imena:

namespace MyNamespace {
    export class Foo { }
}

namespace MyNamespace.Foo {
    export class Bar { }
}

Odgovor #4

Ako se nalazite u kontekstu datoteke deklaracije tipa, to možete učiniti miješanjem klasa i prostora imena:

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

Odgovor #5

Statičko ugnježđivanje

Definiranje statičke ugniježđene klase Foo.Bar može se napraviti na sljedeća dva načina.

  1. Opcija 1: Implementacija Bar unutar namespace-a Foo.
    Tip je automatski deklariran korištenjem spajanja deklaracija.

    class Foo { }
    
    namespace Foo {
        export class Bar { }
    }
    
    let bar: Foo.Bar = new Foo.Bar()
    
  2. Opcija 2: Implementacija Bar unutar klase Foo.
    Tip je deklariran u ambijentalnoj deklaraciji prostora imena.

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

Ne-statičko ugniježđivanje

Definiranje nestatističke ugniježdene klase Foo.prototype.Bar može se izvršiti na sljedeći način.
Tip se ponovno deklarira unutar ambientne deklaracije prostorom imena.

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

Napomena: poziv new Foo.prototype.Bar() ne radi, iako je valjan TypeScript čak i bez deklaracije tipa.

Povezani članci