我运行npm start时收到以下错误:
@ typescript-eslint / no-namespace:自定义TypeScript模块和命名空间不如ES2015模块语法更佳
namespace InternalThings {...}
我试图研究这个问题,但是非常令人困惑。
为什么会出现这种情况? 该如何解决?
我尝试在我的tsconfig.json上添加一些标志,但到目前为止没有成功;
我运行npm start时收到以下错误:
@ typescript-eslint / no-namespace:自定义TypeScript模块和命名空间不如ES2015模块语法更佳
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 文件,并添加以下行:
如果您不喜欢这个规则并想要完全禁用它,那么请编辑您的 .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();
如果您想处理Lint错误而不破坏任何当前实现,可以执行以下操作,但在承诺执行此操作之前,您应该确实查看上面的答案:https://dev59.com/elMH5IYBdhLWcg3wyy3F#63574739
实施
export namespace Container {
export function someCall() { }
export function anotherCall() { }
}
消费者
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,
}
您还可以将函数调用定义并封装到对象中,如下所示:
export const Container = {
someCall() {},
anotherCall() {},
}
如果你有一个庞大的代码库,并想要“快速”使你的代码符合linter规范,可以像上面那样进行重构。请确保考虑本回答中提到的https://dev59.com/elMH5IYBdhLWcg3wyy3F#63574739和其中的原因。
归根结底,最快的修复方法是关闭这个linting规则,正如本回答所述:https://dev59.com/elMH5IYBdhLWcg3wyy3F#58271234
如果你从头开始并遇到了此问题,我建议使用现代实现作为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'
Express.Request
?我不确定你是否可以在没有命名空间的情况下封装类型。除非Request
是顶级导出的,然后你需要import * as Express from './myExpress'
。我对你的命名冲突和你的确切目标有一些担忧。 - undefined