簡體   English   中英

ES2015 模塊語法優於自定義 TypeScript 模塊和命名空間@typescript-eslint/no-namespace

[英]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

如果您發現該規則有用並希望保留它,那么您需要修改您的代碼以使用importexport而不是命名空間。 請參閱規則的文檔,了解什么是修復。

如果您喜歡該規則,但想禁用該行的規則,請在其上方添加以下內容:

// 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 模塊語法(導入/導出)

參考https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-namespace.md

修復 Lint 錯誤,同時保持相同 API

如果您想在不破壞任何當前實現的情況下處理 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()

選項1

// 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,
}

選項 2

您還可以將 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM