全局增强是否需要作为消费者的副作用而导入?

问题描述 投票:0回答:1

我有一个名为 core.error 的包。在这个包中我有两个文件

global.d.ts

export {};

declare global {
  export interface Error {
    foo(): void;
  }
}

index.ts

Error.prototype.foo = function (this: Error): void {
 
};

export const dooFoo = (err:Error) : void => {
  err.foo();
}

现在我在我的第二个项目中将此包作为依赖项。看来全局增强代码只有在我这样做时才会被执行。

import "core.error"

const err = new Error();
err.foo();

但是当我尝试仅导入

dooFoo
函数时,我会得到一个 runtme
TypeError
说“TypeError:err.foo 不是函数”。

import { dooFoo } from "core.error"

const err = new Error();
err.foo();

这是预期的行为吗?如果是这样,我需要像这样从我的模块导入两次吗?

import "core.error"
import { dooFoo } from "core.error"

const err = new Error();
dooFoo(err.foo());

还有其他解决方案可以正确加载和运行 Monkeypatches 全局变量的模块代码吗?

更新

提问前已完成阅读

更新2

index.ts 的声明文件如下所示

/// <reference types="node" />
export declare const dooFoo : (error: Error ) => void;

tsconfig.json 看起来像这样

{
  "compilerOptions": {
    "module": "ES2022",
    "target": "ES2022",
    "allowJs": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "moduleResolution": "Bundler",
    "resolveJsonModule": true,
    "strict": true,
    "outDir": "./build"
  },
  "include": ["source"],
  "exclude": ["node_modules", "tests", "build"]
}
javascript node.js typescript monkeypatching
1个回答
0
投票

问题在于不了解导入省略是如何工作的。

通过这样做,导入语句将在编译的js中被完全删除。

index.ts

import { dooFoo } from "core.error"

const err = new Error();
err.foo();

编译结果index.js

const err = new Error();
err.foo(); //  Will throw a TypeError

另一方面,如果我使用 dooFoo 函数,导入将被保留。

index.ts

import { dooFoo } from "core.error"

const err = new Error();
err.foo(); 
dooFoo(err);

编译结果index.js

import { dooFoo } from "core.error"

const err = new Error();
err.foo(); // No TypeError because side effect was loaded
dooFoo(err);

解决方案#1

通过导入显式加载副作用。

import "core.error"

const err = new Error();
err.foo(); // No TypeError because side effect was loaded

解决方案#2

启用

verbatimModuleSyntax

import { dooFoo } from "core.error"

const err = new Error();
err.foo(); // No TypeError because side effect was loaded

即使从未使用过 dooFoo,导入也将保留在编译后的 JS 中。

© www.soinside.com 2019 - 2024. All rights reserved.