Можете ли вы создавать вложенные классы в TypeScript?


89

Есть ли способ вкладывать классы в TypeScript. Например, я бы хотел использовать их как:

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

2
Для более старых машинописных текстов (<1.6) см. Любой способ вложить классы в машинописный текст?
Рахул Трипати

Ответы:


131

Начиная с TypeScript 1.6 у нас есть выражения классов ( ссылка ).

Это означает, что вы можете делать следующее:

class Foo {
    static Bar = class {

    }
}

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

1
этот пример не работает в Typescript 1.6.3: Ошибка TS4028 Открытое статическое свойство «Панель» экспортированного класса имеет или использует частное имя «(Анонимный класс)».
Сергей

1
@Sergey У меня была такая же проблема, поэтому я начал использовать пространства имен в соответствии с моим ответом ниже.
Дэн Деф

Есть ли способ создать интерфейс внутри класса? то есть, если мы хотим, чтобы этот Бар был интерфейсом
RoG

@LittaHervi - одним из вариантов использования может быть возврат частной реализации внешнего интерфейса, например, из фабричного метода. Другим примером из Java (и других) являются итераторы, которым требуется привилегированный доступ к переменным-членам их содержащего класса и через правила области действия автоматически делают это, но вы никогда не хотите, чтобы они экспортировались и создавались напрямую.
Дэйв

30

Вот более сложный вариант использования с использованием выражений классов .

Это позволяет внутреннему классу получать доступ к privateчленам внешнего класса.

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

кодовый ключ


3
@RyanCavanaugh Является ли возможность доступа к закрытым членам внутри выражения "внутреннего" класса ошибкой?
bnieland

5
Я подтвердил, что это правильное использование с командой TypeScript. github.com/Microsoft/TypeScript/issues/…
bnieland 01

1
возможно ли получить доступ к родительскому контексту, не передавая это напрямую?
shabunc

@shabunc, насколько мне известно,
bnieland

1
Именно то, что я искал, спасибо!
Филипп,

19

Я не мог заставить это работать с экспортированными классами без получения ошибки компиляции, вместо этого я использовал пространства имен :

namespace MyNamespace {
    export class Foo { }
}

namespace MyNamespace.Foo {
    export class Bar { }
}

Тем же. «Foo» относится только к типу, но здесь используется как пространство имен.
Уилл Бисон

12

Если вы находитесь в контексте файла объявления типа, вы можете сделать это, смешав классы и пространства имен:

// 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();
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.