Typescript: видимость в одном и том же пространстве имен для нескольких файлов - PullRequest
0 голосов
/ 20 сентября 2018

Можете ли вы помочь мне - это ошибка или я неправильно понимаю документацию?

У меня есть два файла в пространстве имен - ниже вы найдете более простую версию.

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

Однако tsc жалуется, что не может найти имя «Диспетчер».Почему это происходит?Я неправильно понимаю документацию в данный момент?Или это просто ошибка компилятора?Было бы обидно, если бы это было первое, потому что только видимость пространства имен очень помогла бы для модульного тестирования и инкапсуляции.

Код:

(код изменен для простоты. Если присутствуют синтаксические ошибки,они вызваны этим):

Application.ts:

/// <reference path="Dispatcher.ts"/>
namespace Application {
    export class Application {
        constructor() {
            new Dispatcher(); 
        }
    }
}

Dispatcher.ts:

namespace Application {
    class Dispatcher { /* ... */ }
}

1 Ответ

0 голосов
/ 20 сентября 2018

В документации Typescript говорится, что «Несмотря на то, что файлы являются отдельными, каждый из них может вносить свой вклад в одно и то же пространство имен и может использоваться, как если бы они все были определены в одном».

Это зависит от точного определения «внести вклад в то же пространство имен».В настоящее время интерпретация такова: «все, что экспортируется, доступно везде, все, что не экспортировано, доступно только внутри той части пространства имен, где это определено».Вот как это объясняется в спецификации языка :

Пространства имен обеспечивают механизм для организации кода и объявлений в иерархиях именованных контейнеров.Пространства имен имеют именованные члены, каждое из которых обозначает значение, тип или пространство имен или некоторую их комбинацию, и эти члены могут быть локальными или экспортированными.Тело пространства имен соответствует функции, которая выполняется один раз, тем самым обеспечивая механизм для поддержания локального состояния с гарантированной изоляцией.Пространства имен можно рассматривать как формализацию шаблона выражения немедленного вызова функции (IIFE).

Если существует несколько объявлений одного и того же пространства имен, каждое из них компилируется в отдельный IIFE., как видно из скомпилированного кода javascript для Dispatcher.ts:

var Application;
(function (Application) {
    class Dispatcher {
    }
})(Application || (Application = {}));

В результате область действия Dispatcher находится внутри функции и недоступна извне.

Даже если вы дважды повторили namespace Application в одном и том же файле, каждый из них определил бы свою собственную копию Dispatcher - для этого кода нет ошибки:

namespace Application {
    class Dispatcher { /* ... */ }
}

namespace Application {
    class Dispatcher { /* ... */ }
}

единственный способ сделать Dispatcher доступным извне namespace { ... } - это экспортировать его.При экспорте Dispatcher становится свойством Application объекта:

namespace Application {
    export class Dispatcher { /* ... */ }
}

скомпилированного кода:

var Application;
(function (Application) {
    class Dispatcher {
    }
    Application.Dispatcher = Dispatcher;
})(Application || (Application = {}));

Это поведение имеет смысл с точки зрения реализации.Было бы очень сложно реализовать пространство имен, чтобы неэкспортированные объекты были общими для всех экземпляров пространства имен, но не были доступны извне.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...