Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
396 views
in Technique[技术] by (71.8m points)

javascript - 如何将名称空间与TypeScript外部模块一起使用?(How do I use namespaces with TypeScript external modules?)

I have some code:

(我有一些代码:)

baseTypes.ts

(baseTypes.ts)

export namespace Living.Things {
  export class Animal {
    move() { /* ... */ }
  }
  export class Plant {
    photosynthesize() { /* ... */ }
  }
}

dog.ts

(狗狗)

import b = require('./baseTypes');

export namespace Living.Things {
  // Error, can't find name 'Animal', ??
  export class Dog extends Animal {
    woof() { }
  }
}

tree.ts

()

// Error, can't use the same name twice, ??
import b = require('./baseTypes');
import b = require('./dogs');

namespace Living.Things {
  // Why do I have to write b.Living.Things.Plant instead of b.Plant??
  class Tree extends b.Living.Things.Plant {

  }
}

This is all very confusing.

(这一切都很令人困惑。)

I want to have a bunch of external modules all contribute types to the same namespace, Living.Things .

(我想要一堆外部模块,所有模块都向同一名称空间Living.Things提供类型。)

It seems that this doesn't work at all -- I can't see Animal in dogs.ts .

(看来这根本不起作用-在dogs.ts不到Animal 。)

I have to write the full namespace name b.Living.Things.Plant in tree.ts .

(我要写完整的命名空间名b.Living.Things.Planttree.ts 。)

It doesn't work to combine multiple objects in the same namespace across file.

(在整个文件的同一名称空间中组合多个对象是行不通的。)

How do I do this?

(我该怎么做呢?)

  ask by Ryan Cavanaugh translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Candy Cup Analogy(糖果杯比喻)

Version 1: A cup for every candy(第1版:每个糖果都有一个杯子)

Let's say you wrote some code like this:

(假设您编写了以下代码:)

Mod1.ts

(Mod1.ts)

export namespace A {
    export class Twix { ... }
}

Mod2.ts

(Mod2.ts)

export namespace A {
    export class PeanutButterCup { ... }
}

Mod3.ts

(Mod3.ts)

export namespace A {
     export class KitKat { ... }
}

You've created this setup:

(您已创建此设置:)

在此处输入图片说明

Each module (sheet of paper) gets its own cup named A .

(每个模块(纸)都有自己的杯子 A)

This is useless - you're not actually organizing your candy here, you're just adding an additional step (taking it out of the cup) between you and the treats.

(这是没有用的-您实际上不是在这里整理糖果,只是在您和零食之间添加了一个额外的步骤(将其从杯子中取出)。)


Version 2: One cup in the global scope(第2版??:全球范围内一杯)

If you weren't using modules, you might write code like this (note the lack of export declarations):

(如果您不使用模块,则可以编写如下代码(请注意缺少export声明):)

global1.ts

(global1.ts)

namespace A {
    export class Twix { ... }
}

global2.ts

(global2.ts)

namespace A {
    export class PeanutButterCup { ... }
}

global3.ts

(global3.ts)

namespace A {
     export class KitKat { ... }
}

This code creates a merged namespace A in the global scope:

(这段代码在全局范围内创建了一个合并的命名空间A :)

在此处输入图片说明

This setup is useful, but doesn't apply in the case of modules (because modules don't pollute the global scope).

(此设置很有用,但不适用于模块(因为模块不会污染全局范围)。)


Version 3: Going cupless(版本3:无杯)

Going back to the original example, the cups A , A , and A aren't doing you any favors.

(回到原始示例,杯子AAA对您没有任何帮助。)

Instead, you could write the code as:

(相反,您可以将代码编写为:)

Mod1.ts

(Mod1.ts)

export class Twix { ... }

Mod2.ts

(Mod2.ts)

export class PeanutButterCup { ... }

Mod3.ts

(Mod3.ts)

export class KitKat { ... }

to create a picture that looks like this:

(创建一个看起来像这样的图片:)

在此处输入图片说明

Much better!

(好多了!)

Now, if you're still thinking about how much you really want to use namespace with your modules, read on...

(现在,如果您仍在考虑要在模块中真正使用名称空间的内容,请继续阅读...)


These Aren't the Concepts You're Looking For(这些不是您要寻找的概念)

We need to go back to the origins of why namespaces exist in the first place and examine whether those reasons make sense for external modules.

(我们需要回到为什么命名空间首先存在的起源,并检查这些原因对于外部模块是否有意义。)

Organization : Namespaces are handy for grouping together logically-related objects and types.

(组织 :命名空间非常便于将逻辑相关的对象和类型组合在一起。)

For example, in C#, you're going to find all the collection types in System.Collections .

(例如,在C#中,您将在System.Collections找到所有集合类型。)

By organizing our types into hierarchical namespaces, we provide a good "discovery" experience for users of those types.

(通过将我们的类型组织到分层名称空间中,我们为这些类型的用户提供了良好的“发现”体验。)

Name Conflicts : Namespaces are important to avoid naming collisions.

(名称冲突 :命名空间对于避免命名冲突很重要。)

For example, you might have My.Application.Customer.AddForm and My.Application.Order.AddForm -- two types with the same name, but a different namespace.

(例如,您可能具有My.Application.Customer.AddFormMy.Application.Order.AddForm两种名称相同但名称空间不同的类型。)

In a language where all identifiers exist in the same root scope and all assemblies load all types, it's critical to have everything be in a namespace.

(在一种语言中,所有标识符都存在于同一根作用域中,并且所有程序集都加载所有类型,将所有内容都放在命名空间中至关重要。)

Do those reasons make sense in external modules?

(这些原因在外部模块中有意义吗?)

Organization : External modules are already present in a file system, necessarily.

(组织 :外部模块已必存在于文件系统中。)

We have to resolve them by path and filename, so there's a logical organization scheme for us to use.

(我们必须通过路径和文件名来解析它们,因此有一种逻辑上的组织方案可供我们使用。)

We can have a /collections/generic/ folder with a list module in it.

(我们可以在其中包含一个list模块的/collections/generic/文件夹中。)

Name Conflicts : This doesn't apply at all in external modules.

(名称冲突 :这根本不适用于外部模块。)

Within a module, there's no plausible reason to have two objects with the same name.

(一个模块中,没有任何理由使两个对象具有相同的名称。)

From the consumption side, the consumer of any given module gets to pick the name that they will use to refer to the module, so accidental naming conflicts are impossible.

(从使用方来讲 ,任何给定模块的使用者都可以选择他们将用来引用该模块的名称,因此不可能发生意外的命名冲突。)


Even if you don't believe that those reasons are adequately addressed by how modules work, the "solution" of trying to use namespaces in external modules doesn't even work.

(即使您不相信模块的工作方式已充分解决了这些原因,尝试在外部模块中使用名称空间的“解决方案”甚至都不起作用。)

Boxes in Boxes in Boxes(盒子里的盒子盒子里的盒子)

A story:

(一个故事:)

Your friend Bob calls you up.

(您的朋友鲍勃给您打电话。)

"I have a great new organization scheme in my house", he says, "come check it out!".

(他说:“我的房子里有一个很棒的新组织方案”,“来看看!”。)

Neat, let's go see what Bob has come up with.

(整洁,让我们看看鲍勃想出了什么。)

You start in the kitchen and open up the pantry.

(您从厨房开始,打开厨房。)

There are 60 different boxes, each labelled "Pantry".

(有60个不同的框,每个框标记为“ Pantry”。)

You pick a box at random and open it.

(您随机选择一个盒子并打开它。)

Inside is a single box labelled "Grains".

(里面是一个标有“谷物”的盒子。)

You open up the "Grains" box and find a single box labelled "Pasta".

(您打开“谷物”框,找到一个标有“意大利面”的框。)

You open the "Pasta" box and find a single box labelled "Penne".

(您打开“面食”框,找到一个标有“ Penne”的框。)

You open this box and find, as you expect, a bag of penne pasta.

(您打开此盒子,然后按您的期望找到一袋通心粉。)

Slightly confused, you pick up an adjacent box, also labelled "Pantry".

(有点困惑,您拿起一个相邻的框,也标记为“ Pantry”。)

Inside is a single box, again labelled "Grains".

(里面是一个单独的盒子,再次标记为“谷物”。)

You open up the "Grains" box and, again, find a single box labelled "Pasta".

(打开“谷物”框,然后再次找到一个标记为“意大利面”的框。)

You open the "Pasta" box and find a single box, this one is labelled "Rigatoni".

(您打开“面食”框并找到一个框,该框标记为“ Rigatoni”。)

You open this box and find... a bag of rigatoni pasta.

(您打开这个盒子,然后发现...一包通心粉通心粉。)

"It's great!"

(“这很棒!”)

says Bob.

(鲍勃说。)

"Everything is in a namespace!".

(“一切都在名称空间中!”。)

"But Bob..." you reply.

(“但是鲍勃……”你回答。)

"Your organization scheme is useless. You have to open up a bunch of boxes to get to anything, and it's not actually any more convenient to find anything than if you had just put everything in one box instead of three . In fact, since your pantry is already sorted shelf-by-shelf, you don't need the boxes at all. Why not just set the pasta on the shelf and pick it up when you need it?"

(“您的组织方案是无用的。您必须打开一堆箱子才能接触到任何东西,而要找到任何东西实际上比将所有东西都放在一个而不是三个箱子里更方便。事实上,由于您的食品储藏室已经按架子分类了,您根本不需要盒子了。为什么不把意大利面放在架子上,并在需要时将其拿起呢?”)

"You don't understand -- I need to make sure that no one else puts something that doesn't belong in the 'Pantry' namespace. And I've safely organized all my pasta into the Pantry.Grains.Pasta namespace so I can easily find it"

(“您不明白-我需要确保没有其他人将不属于'Pantry'名称空间的内容放入其中。而且我已经将所有面食安全地组织到Pantry.Grains.Pasta名称空间中,因此我可以轻松找到它”)

Bob is a very confused man.

(鲍勃是个很困惑的人。)

Modules are Their Own Box(模块是他们自己的盒子)

You've probably had something similar happen in real life: You order a few things on Amazon, and each item shows up in its own box, with a smaller box inside, with your item wrapped in its own packaging.

(您可能在现实生活中也发生过类似的事情:您在Amazon上订购了几样东西,每个项目都显示在自己的盒子里,里面有一个较小的盒子,您的项目包装在自己的包装中。)

Even if the interior boxes are similar, the shipments are not usefully "combined".

(即使内部箱相似,也不能有效地将货物“合并”。)

Going with the box analogy, the key observation is that external modules are their own box .

(与盒子类似,关键的观察是外部模块是它们自己的盒子 。)

It might be a very complex item with lots of functionality, but any given external module is its own box.

(它可能是一个非常复杂的项目,具有很多功能,但是任何给定的外部模块都是它自己的盒子。)


Guidance for External Modules(外部模块指南)

Now that we've figured out that we don't need to use 'namespaces', how should we organize our modules?

(既然我们已经知道我们不需要使用“命名空间”,那么我们应该如何组织模块?)

Some guiding principles and examples follow.

(遵循一些指导原则和示例。)

Export as close to top-level as possible(导出尽可能接近顶层)

  • If you're only exporting a single class or function, use export default :

    (如果仅导出单个类或函数,请使用export default :)

MyClass.ts

(MyClass.ts)

export default class SomeType {
  constructor() { ... }
}

MyFunc.ts

(我的功能)

function getThing() { return 'thing'; 

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...