[英]Using ES2015 Modules In TypeScript Without A Module Loader
[英]ES2015 module syntax is preferred over custom TypeScript modules and namespaces @typescript-eslint/no-namespace
我在運行 npm 啟動時收到以下錯誤:
ES2015 模塊語法優於自定義 TypeScript 模塊和命名空間@typescript-eslint/no-namespace
namespace InternalThings {...}
我試圖研究這個,但它非常令人困惑。
為什么會這樣? 如何解決?
我試圖在我的 tsconfig.json 上放置一些標志,但到目前為止沒有成功;
這是由以下 lint 規則引起的 lint 錯誤: https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-namespace.md
如果您發現該規則有用並希望保留它,那么您需要修改您的代碼以使用import
和export
而不是命名空間。 請參閱規則的文檔,了解什么是修復。
如果您喜歡該規則,但想禁用該行的規則,請在其上方添加以下內容:
// eslint-disable-next-line @typescript-eslint/no-namespace
如果您不喜歡該規則並想完全禁用它,請編輯您的 .eslintrc 文件以包含以下行:
rules: {
"@typescript-eslint/no-namespace": "off"
}
要修復此錯誤,而不是:
export namespace InternalThings {
export function myFunction() {
}
export class MyClass {
}
}
import { InternalThings } from './internal-things';
InternalThings.myFunction();
您直接公開命名空間的所有成員:
export function myFunction() {
}
export class MyClass {
}
你像這樣導入它:
import * as InternalThings from './internal-things';
InternalThings.myFunction();
主要思想是您的模塊的用戶只能導入他們想要的內容,或者以不同的方式命名您的模塊:
import * as CustomModuleName from './internal-things';
CustomModuleName.myFunction();
import { MyClass } from './internal-things';
let field = new MyClass();
錯誤來自 eslint。 你必須要么忽略配置中的“@typescript-eslint/no-namespace”規則,要么使用 ES6 重寫你的代碼。
自定義 TypeScript 模塊(模塊 foo {})和命名空間(命名空間 foo {})被認為是組織 TypeScript 代碼的過時方式。 現在首選 ES2015 模塊語法(導入/導出)
如果您想在不破壞任何當前實現的情況下處理 lint 錯誤,您可以執行以下操作,但在提交之前您應該真正查看上述答案: https://stackoverflow.com/a/63574739/349659
Implementation
export namespace Container {
export function someCall() { }
export function anotherCall() { }
}
Consumer
import { Container } from './Container'
Container.someCall()
Container.anotherCall()
// These are essentially private
function someCall() { }
function anotherCall() { }
// We expose them here
// This feels like a step towards CommonJS, but is valid ES Module code
export const Container = {
someCall,
anotherCall,
}
您還可以將 function 調用直接定義並封裝到 object 中,如下所示:
export const Container = {
someCall() {},
anotherCall() {},
}
如果你有一個龐大的代碼庫並且想要“快速”安撫你的 linter,你可以像上面那樣進行重構。 請務必考慮這個答案https://stackoverflow.com/a/63574739/349659及其背后的原因。
歸根結底,不需要更改代碼的最快修復方法是簡單地關閉此 linting 規則,如此答案中所述: https://stackoverflow.com/a/58271234/349659
如果您從頭開始並遇到這個問題,我會考慮使用現代實現作為 linter 提示,但您可能會發現您喜歡命名空間並且也只是想要它們。 如果您是團隊的一員,您可能希望首先獲得他們的反饋並遵循團隊標准。
我遇到的一種情況是在同一個文件中有多個命名空間。 在這種情況下,您可能會在刪除命名空間后發生名稱沖突。
export namespace Container {
export function someCall() { }
export function anotherCall() { }
}
export namespace AnotherContainer {
export function someCall() { }
export function anotherCall() { }
}
在這種情況下,當您刪除命名空間時,您可以重命名沖突,同時保持導出,如下所示:
function containerSomeCall() { }
function containerAnotherCall() { }
export const Container = {
someCall: containerSomeCall,
anotherCall: containerAnotherCall,
}
function anotherContainerSomeCall() { }
function anotherContainerAnotherCall() { }
export const AnotherContainer = {
someCall: anotherContainerSomeCall,
anotherCall: anotherContainerAnotherCall,
}
另一種選擇是將它們解耦到自己的文件中。 如果您想維護原始文件的導出,盡管您需要導入並公開它們,這可能看起來是重復的,但可能是朝着更大重構的間歇性步驟(稍后更新導入以指向新文件)。 如果您願意,這也允許您開始編寫更現代的 ESM 代碼,同時通過舊模塊代理新導出。
Container.ts
function someCall() { }
function anotherCall() { }
export const Container = {
someCall,
anotherCall,
}
AnotherContainer.ts
function someCall() { }
function anotherCall() { }
export const AnotherContainer = {
someCall,
anotherCall,
}
OriginalFile.ts
export * from './Container'
export * from './AnotherContainer'
我們可以通過舊的原始模塊代理新的 ESM 模塊。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.