目次
序文
この記事はTypeScript 知識のまとめ記事シリーズに含まれています。修正は歓迎です。
前回の記事でTS モジュールを読んでいただければ、TS のモジュールの仕組みについてはある程度理解していただけたと思いますので、この記事では重複した名前のモジュールや宣言の種類のマージと使用法について紹介します。
私たちが同様の概念に初めて触れたのは、関数の記事でした。関数のオーバーロードは宣言のマージです。
宣言のマージとは、コンパイラが同じ名前の宣言を 1 つの宣言にマージし、マージされた宣言が元の 2 つ以上の宣言の特性を同時に持つことを意味します。2 つ以上の変数、型、またはモジュールが同じ変数名で定義されている場合、宣言のマージが発生します。
TS での宣言のマージには、インターフェイス、関数、名前空間、列挙、およびクラス間のマージが含まれます。次に、これらのタイプのマージについてさらに詳しく説明します。
同種合併
インターフェースのマージ
同じメンバー名
インターフェイスのマージにおけるインターフェイスのメンバー名は繰り返すことができますが、タイプは同じである必要があります
interface IAnimal {
name: string
}
interface IAnimal {
name: number // 后续属性声明必须属于同一类型。属性“name”的类型必须为“string”,但此处却为类型“number”
color: string
}
const animal: IAnimal = {
name: "阿黄",
color: "black"
}
正しいスペルは次のとおりです。
// global.d.ts
interface IAnimal {
name: string
}
interface IAnimal {
color: string
}
// 相当于
interface IAnimal {
name: string
color: string
}
// src/index.ts
const animal: IAnimal = {
name: "阿黄",
color: "black"
}
同じメソッド名
2 つのインターフェイスに同じ関数名が出現した場合、関数のオーバーロードに従って処理されます。
// global.d.ts
interface IAnimal {
getVal(val: number): number
}
interface IAnimal {
getVal(val: string): string
}
// 相当于
interface IAnimal {
getVal(val: number): number
getVal(val: string): string
}
// src/index.ts
const animal: IAnimal = {
getVal(val: any) {
return val
}
}
ヒント: アロー関数は関数のオーバーロードをサポートしていませんが、これは関数に関する記事では触れられていませんでした。アロー関数は関数宣言ではなく関数式であるため、関数のオーバーロードはサポートされていません。
関数
関数はこの記事を参照できます
名前空間
モジュール記事の質問に戻りましょう。名前空間はコード ブロックで定義する必要がありますか?
モジュール内で、名前空間の実装では実際に iife (即時実行関数) を使用して外部変数を変更し、カプセル化の目的を達成すると述べました。
// global.d.ts
declare namespace global_type {
interface IAnimal {
name: string
color: string
}
}
declare namespace global_type {
let animal: IAnimal
}
// 相当于
declare namespace global_type {
interface IAnimal {
name: string
color: string
}
// let animal: IAnimal //使用let不能重复定义变量,这句会报错,所以先注释了
}
// src/index.ts
global_type.animal = {
name: "",
color: ""
}
同じ名前の名前空間内の型または変数を直接取得できます。たとえば、上記のコードの IAnimal は、名前空間内で直接取得できます。
列挙する
列挙型もマージ ルールに従い、列挙型のキーはすべて一意の値であるため、重複は許可されません
// global.d.ts
declare enum Position {
x = 0
}
declare enum Position {
y = 1
}
declare enum Position {
z = 2
}
/*相当于
declare enum Position {
x = 0,
y = 1,
z = 2
}*/
// src/index.ts
const { x, y, z } = Position
さまざまな種類の合併
クラスとインターフェース
クラスとインターフェイスの直接マージのルールはインターフェイスの直接マージと同じです
// global.d.ts
declare class Animal {
name: string
}
declare interface Animal {
age: number
}
declare let animal: Animal
// index.ts
animal = new class {
name: string
age: number
}
名前空間と列挙型
名前空間と列挙型が同じ名前の場合、宣言のマージも行われます。上記の名前空間と列挙型の実装原則を組み合わせると、理解するのは難しくありません。この 2 つのマージは、実際には Position オブジェクトのマージとみなすことができます
// global.d.ts
declare enum Position {
x = 0,
y = 1,
z = 2
}
declare namespace Position {
const _x = Position.x
}
/*
可以看成
enum Position {
x = 0,
y = 1,
z = 2,
_x = Position.x
}*/
declare let x: Position.x
declare let y: Position.y
// src/index.ts
x = Position._x
名前空間とクラス
名前空間がクラスとマージされると、対応する属性がクラスに静的に配置されます。名前空間定義は、実際にはコンテキスト内のオブジェクトに属性を割り当てます。名前空間がクラスと一致すると、そのクラスの静的属性を追加するものとみなすことができます。
class Animal {
age: number
}
namespace Animal {
export let age: number = 10
}
console.log(Animal);// [class Animal] { age: 10 }
const animal = new Animal()
animal.age = Animal.age
ヒント: 名前空間宣言は、マージ先のクラスまたは関数の前に置くことはできません。
名前空間と関数
関数はクラスに似ており、独自の静的プロパティを追加します。
function Animal() {
return Animal.age// 取自身的age属性
}
namespace Animal {
export let age: number = 10
}
console.log(Animal);// [Function: Animal] { age: 10 }
const age = Animal()
console.log(age);// 10
最後に書きます
以上が記事の全内容ですが、主にTSにおける同型と異型のマージについて、関数、名前空間、列挙型、クラス、インターフェースのマージ関係を含めて理解することができます。
最後まで読んでいただき、記事が良いと思っていただけましたら応援していただけると嬉しいです、よろしくお願いします!