Hardhat plugins use Type Extensions to add functionality to existing types.
A Type Extension needs to be reachable by TypeScript for it to take place. If it's in your own codebase, you don't need to do anything special, as in that situation TypeScript evaluates all your files.
When you are distributing a package through npm though, only the imported files of your package, and their transitive dependencies are loaded. If you place a type-extensions.ts file next to your plugin's index.ts file and don't import it in any way, it will be ignored.
Our current recommendation is for plugins to have a top-level
import "./type-extension.ts";
in their index.ts, which works to force TypeScript to apply the extension.
Its drawback is that that import is also present in the compiled index.js, and run when the plugin is loaded without any added benefit.
Instead, we can use this pattern:
export type * from "./type-extensions.ts";
it still forces typescript to apply the type extensions, but it doesn't generate a runtime import.
For this pattern to work, is extremely important that the ./type-extensions.ts file doesn't:
- Produce any side effect
- Export any type
- Has a
export type * from "plugin-dependency"; for each plugin you depend on.
The new updated pattern for type extensions should then be:
- Add
export type * from "./type-extensions.ts"; to your plugin's index.ts
- Do not run any executable code in your
./type-extensions.ts file. Only type-level code is valid.
- Do not export any type from your
type-extension.ts
- Type-extensions don't need to import the modules they are augmenting. This was an incorrect way to force the
.ts file to be treated as a module. Use export {};, or better yet "moduleDetection": "force".
- Do not export any type from your
index.ts, otherwise plugins depending on yours will accidentally re-export it.
To do this, we should:
Hardhat plugins use Type Extensions to add functionality to existing types.
A Type Extension needs to be reachable by TypeScript for it to take place. If it's in your own codebase, you don't need to do anything special, as in that situation TypeScript evaluates all your files.
When you are distributing a package through npm though, only the imported files of your package, and their transitive dependencies are loaded. If you place a
type-extensions.tsfile next to your plugin'sindex.tsfile and don't import it in any way, it will be ignored.Our current recommendation is for plugins to have a top-level
in their
index.ts, which works to force TypeScript to apply the extension.Its drawback is that that import is also present in the compiled
index.js, and run when the plugin is loaded without any added benefit.Instead, we can use this pattern:
it still forces typescript to apply the type extensions, but it doesn't generate a runtime import.
For this pattern to work, is extremely important that the
./type-extensions.tsfile doesn't:export type * from "plugin-dependency";for each plugin you depend on.The new updated pattern for type extensions should then be:
export type * from "./type-extensions.ts";to your plugin'sindex.ts./type-extensions.tsfile. Only type-level code is valid.type-extension.ts.tsfile to be treated as a module. Useexport {};, or better yet"moduleDetection": "force".index.ts, otherwise plugins depending on yours will accidentally re-export it.To do this, we should:
mainandtutorialbranches)