Typescript инициализирует статическую переменную типа класса

#typescript

#typescript

Вопрос:

У меня есть два класса Foo и Bar . В классе Bar у меня вызывается статическая переменная myFoo , и я хочу, чтобы она автоматически инициализировалась:

 class Foo {
}

class Bar {
    static myFoo: Foo = new Foo();
}
 

Однако я получаю эту ошибку:

Ошибка неперехваченной ссылки: Foo не определен

Если я инициализирую эту статическую переменную в Bar конструкторе, тогда она работает нормально:

 class Bar {
    static myFoo: Foo;

    constructor() {
         Bar.myFoo = new Foo();
    }
}
 

Почему это так? Что я сделал не так, когда попытался инициализировать статическую переменную myFoo напрямую?

Ответ №1:

Вы определенно не хотите делать это второе, потому что это будет перезаписываться myFoo каждый раз, когда вы создаете новую панель, и вы, конечно, этого не хотите.

То, что у вас здесь, — это проблема времени выполнения, а не проблема времени компиляции. Foo Класс должен быть загружен до Bar загрузки класса, иначе статический инициализатор завершится ошибкой. Если оба класса находятся в одном файле в указанном выше порядке, это работает. Если классы находятся в отдельных файлах, и вы указываете TypeScript на компиляцию в один файл, он должен определить правильный порядок для вас (хотя в этой области есть ошибки). Если вы компилируете для отдельных файлов, вам нужно будет включить скрипты на страницу в правильном порядке, чтобы удовлетворить зависимость.

Комментарии:

1. действительно, это было потому, что я импортировал файлы скрипта в неправильном порядке. Спасибо!

Ответ №2:

Вы можете просто вызвать инициализацию сразу после объявления класса:

 class MyClass {
    static initialize() {
        // Initialization
    }
}
MyClass.initialize();
 

Ответ №3:

Для этого требуется jQuery, но это то, что я делаю, чтобы иметь эквивалент «статического конструктора».

 namespace SomeNamespace {
   $(() => SomeClass.StaticConstructor());

   export class SomeClass {
      public static StaticConstructor() {
      }
   }
}
 

Это также полезно, например, в качестве «точки входа» вашего приложения.

 namespace SomeNamespace {
   $(() => SomeClass.Start());

   export class SomeClass {
      private static sInstance: SomeClass;

      public static Start() {
         SomeClass.sInstance = new SomeClass();
      }
   }
}
 

Ответ №4:

Как сказал Джеффри Грайковски, ваш второй подход неверен. Вы могли бы просто инициализировать в определении.

 class Bar {
  static myFoo: Foo = new Foo();
}