Подтвердить что ты не робот

Использование пространства имен, распределенного по нескольким файлам модулей в TypeScript

Я начал работу над масштабным проектом машинописи.

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

Я пытался использовать модули/пространства имен и разделять классы на отдельные файлы для каждого с папкой, содержащей пространство имен.

Структура файла:

app.ts
\Classes
---- \Animals
---- ---- Mammals.ts
---- ---- Reptiles.ts

Затем я пытаюсь импортировать все файлы в этом пространстве имен в app.ts, используя что-то вроде: import * as Animals from "./Classes/Animals"

Что касается самих файлов пространства имен, я попробовал следующее, но безуспешно:

namespace Animals {
    export class Mammals {
        constructor() {
        }
    }
}

а также:

module Animals {
    export class Reptiles {
        constructor() {
        }
    }
}

К сожалению, путь никогда не распознается (так как он указывает на папку, а не на один файл). Это вообще возможно? Наличие всех моих классов из одного пространства имен в одном файле приведет к файлам длиной в тысячи строк и для этого проекта, которые невозможно обслуживать.

Я также заметил, что TypeScript 1.5 имеет поддержку tsconfig.json - однако, добавление каждого файла вручную на карту является верным способом возникновения проблем, когда разработчики начинают добавлять классы.

ПРИМЕЧАНИЕ. Я использую Visual Studio 2015, TypeScript 1.5 (я не уверен, как это проверить). У меня также включена поддержка ES6.

4b9b3361

Ответ 1

Используйте реэкспортирование для создания внешнего модуля, который группирует и предоставляет типы из других модулей:

// Classes/Animals.ts
export * from '.\Animals\Mammals';
export * from '.\Animals\Reptiles';

Затем импортируйте типы из нового модуля, как обычно:

// app.ts
import * as Animals from '.\Classes\Animals'

let dog: Animals.Dog;
let snake: Animals.Snake;

или

// app.ts
import { Dog, Snake } from '.\Classes\Animals'

let dog: Dog;
let snake: Snake;

Ответ 2

Нашел способ достичь своей цели, но не с помощью ключевого слова пространства имен.

  1. Классы "Животные", Animal.ts & Mammal.ts & Reptile.ts в пространстве имен.
  2. с index.ts для барреля.
  3. animals.ts для группировки пространства имен.

Animal namespace

Образцы классов:

Classes

index.ts (как баррель)

enter image description here

animals.ts (для группировки пространства имен)

enter image description here

И здесь вы идете о концепции пространства имен.

enter image description here

Ответ 3

Внешние модули подразумевают, что вы загружаете файлы по файлу. И AMD, и CommonJS не имеют такой вещи, как пространство имен. Вы можете использовать некоторую постобработку для связывания файлов в одном модуле.


Далее определяется внутренний модуль:

module Animals {
    export class Reptiles {
        constructor() {
        }
    }
}

Вы не должны использовать для этого import. Animals.Reptiles отображается везде. Единственная цель - загрузить скрипты в правильном порядке (например, базовые классы перед наследниками). Поэтому вы должны перечислить все файлы в ts.config или в другом месте. В моем проекте я использую пакеты в папках и соглашусь добавить @ в имена файлов базовых классов.

Другим решением является использование внешних модулей: AMD (RequireJS) или CommonJS (Browserify). В этом случае удалите верхний уровень module из объявления. Если один файл содержит только один тип, вы можете экспортировать его как корень:

class Reptiles {
    constructor() {
    }
}

export = Reptiles;

Вы можете ссылаться на модуль по пути к файлу:

import Reptilies = require('..\Animals\Reptilies')
var  reptile = new Reptile();

Или с новыми модулями ES6:

export class Reptiles {
    constructor() {
    }
}

import { Reptiles } from '..\Animals\Reptilies';

Ответ 4

Кажется, что нет способа сделать это, используя пространства имен самостоятельно (если вы не хотите использовать модуль Augmentation и declare каждый новый элемент для добавления отдельно); однако пространство имен может быть частью класса, который может быть расширен! Это лучшая альтернатива, которую я могу найти:

CoreLibraryTypes.ts

abstract class Types { }
namespace Types { 
    export class TypeA { }
    export class TypeB { }
    export class TypeC { }
}
export { Types };

CoreTypesExtended.ts

import CoreLibraryTypes from "./CoreLibraryTypes";

abstract class Types extends CoreLibraryTypes { }
namespace Types { 
    export class TypeD { }
    export class TypeE { }
    export class TypeF { }
}
export { Types };

Недостатком, конечно, является то, что только при импорте второго модуля будут добавлены новые типы. Первый модуль останется прежним. В идеале было бы неплохо "обновить" пространство имен типов дополнительными типами (например, из плагинов), чтобы расширение модуля поддерживалось более естественным образом (вместо того, чтобы писать его вручную), но я думаю, что это нужно делать до кто-то понимает, что расширение модулей путем ручного объявления обновленных определений - это всего лишь пол-$ способ сделать то, что пространства имен уже делают (включая классы, как показано выше, которые уже могут использовать слияние пространства имен как часть класса). ;)

Примечание: в примере выше я использовал export { Types }; по причине - это позволит другим дополнить мои модули. Аугментация не поддерживается для экспорта по умолчанию (если это не нужно - сортируйте его практически).