-- Ví dụ Mở rộng namespace trong typescript 2 file khác nhau và những chú ý (ok)

Nếu bạn muốn sử dụng một file khác để kết hợp hai file có cùng một namespace và chạy bằng ts-node, bạn có thể làm theo hướng dẫn sau:


🔹 Tổ chức file

Giả sử bạn có ba file TypeScript:

lessCopyEditproject/
│── file1.ts      // Khai báo namespace lần 1
│── file2.ts      // Mở rộng namespace
│── main.ts       // Sử dụng namespace
│── tsconfig.json // (nếu cần)

1️⃣ Khai báo namespace trong các file

file1.ts

typescriptCopyEditexport namespace MyNamespace {
  export const name = "TypeScript";
}

file2.ts

typescriptCopyEditimport { MyNamespace } from "./file1"; // Import namespace từ file1.ts

export namespace MyNamespace {
  export const version = "5.0";

  export function getInfo() {
    return `${MyNamespace.name} - Version ${version}`;
  }
}

2️⃣ Sử dụng namespace trong file thứ ba

main.ts

typescriptCopyEditimport { MyNamespace } from "./file2"; // Import từ file2 (đã chứa file1)

console.log(MyNamespace.getInfo()); // Output: "TypeScript - Version 5.0"

3️⃣ Chạy bằng ts-node

Trước tiên, nếu bạn chưa cài ts-node, hãy cài đặt nó:

shCopyEditnpm install -g ts-node

Sau đó, chạy trực tiếp file main.ts:

shCopyEditts-node main.ts

🔹 Cấu hình tsconfig.json (Tùy chọn)

Nếu bạn gặp lỗi hoặc muốn đảm bảo TypeScript hoạt động mượt mà, có thể thêm tsconfig.json:

jsonCopyEdit{
  "compilerOptions": {
    "module": "CommonJS",
    "esModuleInterop": true
  }
}

Tóm tắt

  • Dùng export namespace thay vì namespace thuần để có thể import.

  • Dùng import thay vì /// <reference path="..." /> để kết nối file.

  • Chạy bằng ts-node main.ts mà không cần biên dịch trước.

🚀 Bây giờ bạn có thể mở rộng namespace từ nhiều file và chạy bằng ts-node một cách dễ dàng!

🔹Lỗi Individual declarations in merged declaration 'MyNamespace' must be all exported or all local.

Lỗi này xảy ra vì TypeScript yêu cầu rằng tất cả các phần của một namespace phải được xuất (export) hoặc không xuất (local) nhất quán.

🔥 Cách khắc phục lỗi

Bạn có hai cách để giải quyết vấn đề này:


Cách 1: Đảm bảo tất cả namespace đều được export

Nếu bạn muốn sử dụng import/export, tất cả các namespace phải có export.

🔹 Tệp file1.ts

typescriptCopyEditexport namespace MyNamespace {
  export const name = "TypeScript";
}

🔹 Tệp file2.ts

typescriptCopyEditimport { MyNamespace } from "./file1"; // Import namespace từ file1.ts

export namespace MyNamespace {
  export const version = "5.0";

  export function getInfo() {
    return `${MyNamespace.name} - Version ${version}`;
  }
}

🔹 Tệp main.ts

typescriptCopyEditimport { MyNamespace } from "./file2"; // Import từ file2.ts

console.log(MyNamespace.getInfo()); // Output: "TypeScript - Version 5.0"

🔹 Chạy với ts-node

shCopyEditts-node main.ts

Giải thích:

  • Cả file1.tsfile2.ts đều xuất (export) namespace MyNamespace, vì vậy TypeScript không bị lỗi.


Cách 2: Dùng /// <reference path="..." /> nếu không muốn dùng import/export

Nếu bạn không muốn sử dụng import/export, bạn có thể dùng /// <reference path="..." /> để khai báo namespace mà không cần module.

🔹 Tệp file1.ts

typescriptCopyEditnamespace MyNamespace {
  export const name = "TypeScript";
}

🔹 Tệp file2.ts

typescriptCopyEdit/// <reference path="file1.ts" />

namespace MyNamespace {
  export const version = "5.0";

  export function getInfo() {
    return `${name} - Version ${version}`;
  }
}

🔹 Tệp main.ts

typescriptCopyEdit/// <reference path="file1.ts" />
/// <reference path="file2.ts" />

console.log(MyNamespace.getInfo()); // Output: "TypeScript - Version 5.0"

🔹 Chạy với ts-node

Với cách này, ts-node không thể chạy trực tiếp, bạn cần dùng tsc để biên dịch trước:

shCopyEdittsc --outFile output.js file1.ts file2.ts main.ts
node output.js

Giải thích:

  • Vì không sử dụng import/export, các file namespace phải được nối lại bằng /// <reference path="..." />.

  • ts-node không hỗ trợ trực tiếp /// <reference path="..." />, nên bạn phải biên dịch bằng tsc trước khi chạy bằng node.


🚀 Kết luận

  • Cách 1 (export/import): Dùng khi bạn muốn chạy trực tiếp với ts-node.

  • Cách 2 (/// <reference path="..." />): Dùng khi bạn không muốn dùng module nhưng phải biên dịch bằng tsc trước khi chạy.

📌 Nếu bạn muốn code linh hoạt hơn và chạy dễ dàng với ts-node, hãy dùng Cách 1 (export/import). 🚀

You said:

Ví dụ Mở rộng namespace trong typescript 2 file khác nhau

ChatGPT said:

Để mở rộng một namespace trong TypeScript với hai tệp khác nhau, bạn có thể làm như sau:


🏗 Cấu trúc tệp

Giả sử bạn có hai tệp:

lessCopyEditproject/
│── file1.ts   // Định nghĩa namespace
│── file2.ts   // Mở rộng namespace
│── main.ts    // Sử dụng namespace
│── tsconfig.json (tùy chọn)

Cách 1: Dùng export namespaceimport (Chạy được với ts-node)

📌 Tệp file1.ts - Khai báo namespace ban đầu

typescriptCopyEditexport namespace MyNamespace {
  export const name = "TypeScript";
}

📌 Tệp file2.ts - Mở rộng namespace

typescriptCopyEditimport { MyNamespace } from "./file1"; // Import phần khai báo trước đó

export namespace MyNamespace {
  export const version = "5.0";

  export function getInfo() {
    return `${MyNamespace.name} - Version ${version}`;
  }
}

📌 Tệp main.ts - Sử dụng namespace

typescriptCopyEditimport { MyNamespace } from "./file2"; // Import từ file2 (đã chứa file1)

console.log(MyNamespace.getInfo()); // Output: "TypeScript - Version 5.0"

🚀 Chạy với ts-node

shCopyEditts-node main.ts

🔥 Lợi ích của cách này

  • Hoạt động tốt với ts-node (không cần biên dịch trước).

  • Dễ bảo trì vì sử dụng module system (import/export).


Cách 2: Dùng /// <reference path="..." /> (Dành cho biên dịch bằng tsc)

Nếu bạn không muốn dùng import/export, bạn có thể sử dụng /// <reference path="..." /> để kết nối các file.

📌 Tệp file1.ts - Khai báo namespace ban đầu

typescriptCopyEditnamespace MyNamespace {
  export const name = "TypeScript";
}

📌 Tệp file2.ts - Mở rộng namespace

typescriptCopyEdit/// <reference path="file1.ts" />

namespace MyNamespace {
  export const version = "5.0";

  export function getInfo() {
    return `${name} - Version ${version}`;
  }
}

📌 Tệp main.ts - Sử dụng namespace

typescriptCopyEdit/// <reference path="file1.ts" />
/// <reference path="file2.ts" />

console.log(MyNamespace.getInfo()); // Output: "TypeScript - Version 5.0"

🚀 Chạy với tsc

Vì cách này không dùng import/export, ts-node không chạy được trực tiếp. Bạn cần biên dịch trước:

shCopyEdittsc --outFile output.js file1.ts file2.ts main.ts
node output.js

🎯 So sánh hai cách

Cách

Hỗ trợ ts-node?

Cần biên dịch trước?

Dễ dùng?

Cách 1 (export/import)

✅ Có

❌ Không

✅ Dễ

Cách 2 (/// <reference path="..." />)

❌ Không

✅ Có

❌ Khó hơn

📌 Khuyến nghị:

  • Dùng Cách 1 (export/import) nếu bạn muốn code dễ chạy trực tiếp bằng ts-node.

  • Dùng Cách 2 (/// <reference path="..." />) nếu bạn muốn code theo kiểu namespace truyền thống mà không dùng module.

🚀 Bây giờ bạn có thể mở rộng namespace từ nhiều file một cách hiệu quả! 🚀

Last updated