キャンディカップの類推
バージョン1:すべてのキャンディー用のカップ
次のようなコードを書いたとします。
Mod1.ts
export namespace A {
export class Twix { ... }
}
Mod2.ts
export namespace A {
export class PeanutButterCup { ... }
}
Mod3.ts
export namespace A {
export class KitKat { ... }
}
この設定を作成しました:
各モジュール(紙)には、という名前の独自のカップがありA
ます。これは役に立たない- ここで実際にキャンディーを整理するのではなく、あなたとおやつの間に追加のステップ(カップから取り出す)を追加するだけです。
バージョン2:グローバルスコープの1つのカップ
モジュールを使用していない場合は、次のようなコードを記述します(export
宣言がないことに注意してください)。
global1.ts
namespace A {
export class Twix { ... }
}
global2.ts
namespace A {
export class PeanutButterCup { ... }
}
global3.ts
namespace A {
export class KitKat { ... }
}
このコードはA
、グローバルスコープにマージされた名前空間を作成します。
この設定は便利ですが、モジュールの場合には適用されません(モジュールはグローバルスコープを汚染しないため)。
バージョン3:カップレス化
元の例に行く、カップはA
、A
とA
あなたに好意をやっていません。代わりに、コードを次のように書くことができます。
Mod1.ts
export class Twix { ... }
Mod2.ts
export class PeanutButterCup { ... }
Mod3.ts
export class KitKat { ... }
次のような画像を作成します。
ずっといい!
さて、モジュールでネームスペースを本当にどれだけ使用したいかについてまだ考えている場合は、以下を読んでください...
これらはあなたが探している概念ではありません
名前空間が最初に存在する理由の起源に戻り、それらの理由が外部モジュールにとって意味があるかどうかを調べる必要があります。
構成:名前空間は、論理的に関連するオブジェクトとタイプをグループ化するのに便利です。たとえば、C#では、すべてのコレクション型をで検索しSystem.Collections
ます。タイプを階層的な名前空間に編成することにより、これらのタイプのユーザーに優れた「発見」エクスペリエンスを提供します。
名前の競合:名前空間は、名前の競合を回避するために重要です。たとえば、My.Application.Customer.AddForm
とMy.Application.Order.AddForm
-名前が同じで名前空間が異なる2つのタイプがあるとします。すべての識別子が同じルートスコープに存在し、すべてのアセンブリがすべてのタイプをロードする言語では、すべてが名前空間にあることが重要です。
これらの理由は外部モジュールで意味がありますか?
構成:外部モジュールは、必ずファイルシステムにすでに存在しています。それらをパスとファイル名で解決する必要があるため、使用する論理的な編成スキームがあります。モジュールを含む/collections/generic/
フォルダを作成できますlist
。
名前の競合:これは、外部モジュールにはまったく適用されません。モジュール内で、同じ名前の2つのオブジェクトが存在するもっともらしい理由はありません。消費側から、特定のモジュールのコンシューマーは、モジュールを参照するために使用する名前を選択できるため、誤って名前が競合することはありません。
これらの理由がモジュールの動作によって適切に対処されているとは思わない場合でも、外部モジュールで名前空間を使用しようとする「解決策」は機能しません。
ボックスのボックスボックスのボックス
ストーリー:
友達のボブから電話がかかってきました。「私は私の家にすばらしい新しい組織計画を持っています」と彼は言います、「是非チェックしてください!」。きちんと、ボブが思いついたものを見に行きましょう。
あなたは台所から始めて、パントリーを開けます。60の異なるボックスがあり、それぞれに「パントリー」というラベルが付いています。あなたはランダムに箱を選んでそれを開きます。内部には、「穀物」というラベルの付いた1つのボックスがあります。「穀物」ボックスを開くと、「パスタ」というラベルの付いた1つのボックスが見つかります。「パスタ」ボックスを開き、「ペンネ」というラベルの付いた1つのボックスを見つけます。あなたはこの箱を開けて、予想通り、ペンネパスタの袋を見つけます。
少し混乱して、「パントリー」というラベルが付いた隣接するボックスを選択します。中には「穀物」というラベルの付いた1つのボックスがあります。「Grains」ボックスを開き、再び「Pasta」というラベルの付いた1つのボックスを見つけます。「パスタ」ボックスを開いて1つのボックスを見つけます。このボックスには「リガトーニ」というラベルが付いています。あなたはこの箱を開けて…リガトーニのパスタの袋を見つけます。
"それは素晴らしい!" ボブは言います。「すべてが名前空間にあります!」
「でもボブ...」と答える。「あなたの組織スキームは役に立たない。何かに到達するためにはたくさんの箱を開ける必要があり、3つではなく1つの箱にすべてを入れただけの場合よりも、実際に何かを見つけるのは便利ではありません。実際、パントリーはすでに棚ごとに並べ替えられています。箱はまったく必要ありません。パスタを棚に置いて、必要なときにそれを受け取るのはどうですか?」
「理解できません。「パントリー」名前空間に属さないものを他の人が入れないようにする必要があります。すべてのパスタをPantry.Grains.Pasta
名前空間に安全に整理して、簡単に見つけられるようにしました」
ボブはとても混乱している人です。
モジュールは独自のボックスです
おそらく、実際に似たようなことが起こったでしょう。Amazonでいくつか注文すると、それぞれのアイテムが専用のボックスに、小さなボックスが中にあり、独自のパッケージに包まれて現れます。内部の箱が似ていても、積荷は有効に「結合」されていません。
ボックスの類推で言えば、重要な観察は、外部モジュールは独自のボックスであるということです。多くの機能を備えた非常に複雑なアイテムかもしれませんが、特定の外部モジュールは独自のボックスです。
外部モジュールのガイダンス
「名前空間」を使用する必要がないことがわかったので、モジュールをどのように整理したらよいでしょうか。次に、いくつかの指針となる例と例を示します。
可能な限りトップレベルに近いエクスポート
- 単一のクラスまたは関数のみをエクスポートする場合は、次を使用します
export default
。
MyClass.ts
export default class SomeType {
constructor() { ... }
}
MyFunc.ts
function getThing() { return 'thing'; }
export default getThing;
消費
import t from './MyClass';
import f from './MyFunc';
var x = new t();
console.log(f());
これは消費者にとって最適です。彼らはあなたのタイプに好きな名前を付けることができ(t
この場合)、オブジェクトを見つけるために余分な点を打つ必要はありません。
- 複数のオブジェクトをエクスポートする場合は、すべてを最上位に配置します。
MyThings.ts
export class SomeType { ... }
export function someFunc() { ... }
消費
import * as m from './MyThings';
var x = new m.SomeType();
var y = m.someFunc();
- 多数のものをエクスポートする場合は、
module
/ namespace
キーワードを使用する必要があります。
MyLargeModule.ts
export namespace Animals {
export class Dog { ... }
export class Cat { ... }
}
export namespace Plants {
export class Tree { ... }
}
消費
import { Animals, Plants} from './MyLargeModule';
var x = new Animals.Dog();
赤い旗
次のすべては、モジュール構造化の赤旗です。これらのいずれかがファイルに当てはまる場合は、外部モジュールの名前空間を作成していないことを再確認してください。
- トップレベルの宣言のみが含まれるファイル
export module Foo { ... }
(Foo
すべてを削除して、1レベル上に移動)
- 単一のファイル
export class
または含まexport function
れていないファイルexport default
export module Foo {
トップレベルで同じである複数のファイル(これらが1つに結合されるとは思わないでくださいFoo
!)