Currently running into some issues while trying to do type augmentation on a third-party module.
Let's say we have module X which defines a base type, in this case ICtxData. We have module Y which augments type, and our application which uses both.
If the application uses the same import for X that module Y uses to augment, the augmentation is working:
// X
interface ICtxData {}
// Y
declare module "https://raw.githubusercontent.com/routexjs/deroutex/master/mod.ts" {
interface ICtxData {
body?: any;
bodyParser?: string
}
}
// Application
import "y"; // mock
import "https://raw.githubusercontent.com/routexjs/deroutex/master/mod.ts";
// string | undefined
ctx.data.bodyParser
However, if it uses a different import, it does not work:
// X
interface ICtxData {}
// Y
declare module "https://raw.githubusercontent.com/routexjs/deroutex/master/mod.ts" {
interface ICtxData {
body?: any;
bodyParser?: string
}
}
// Application
import "y"; // mock
import "https://raw.githubusercontent.com/routexjs/deroutex/45caec11f9892ba8137bffd9ac97f9765895c743/mod.ts";
// any
ctx.data.bodyParser
I'm not sure how Deno could solve this, since we don't have identifiers for module.
As you pointed out Deno does support it. You just have to know the module name. Let alone augmenting existing TypeScript is "dangerous" in my opinion, like augmenting built in globals.
Your best approach is to import whatever you want, augment it, and re-export it, and any code the needs the argumentation would depend on that re-export.
Hi, I’m running into module augmentation issues as well. I’m trying to import a JS file with a typescript generated d.ts reference via unpkg, but the file contains a module augmentation error.
server.tsx
/** @jsx createElement */
// @deno-types="https://unpkg.com/@bikeshaving/[email protected]/index.d.ts"
import {createElement} from "https://unpkg.com/@bikeshaving/[email protected]/index.js";
// @deno-types="https://unpkg.com/@bikeshaving/[email protected]/html.d.ts"
import {renderer} from "https://unpkg.com/@bikeshaving/[email protected]/html.js";
console.log(renderer.render(<div>Hello world</div>, document.body));
tsconfig.json
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"lib": ["esnext", "dom"]
}
}
command
deno run -c tsconfig.json server.tsx
The above code throws the following error
[ERROR]: Invalid module name in augmentation. Module './index' resolves to an untyped module at 'https://unpkg.com/@bikeshaving/[email protected]/index.js', which cannot be augmented.
declare module "./index" {
because of this code in https://unpkg.com/@bikeshaving/crank@0.3.0/html.d.ts.
declare module "./index" {
interface EventMap extends GlobalEventHandlersEventMap {
}
}
Let alone augmenting existing TypeScript is "dangerous" in my opinion, like augmenting built in globals.
Augmenting code is a useful pattern when you don’t want plugins and extensions to clash, I’d hate to see “best practices” stuff block module augmentation support in Deno. I’m thinking of creating an artificial global module to solve this issue, but it would be nice for relative path module augmentation to work too.
I think the main "issue" here is the non-static module names (modules can be imported from multiple URLs). I'm going to leave this open, but I too would consider this a non-issue, and should be done in a more proper way if possible.
@Cretezy A simple solution is to create a tsconfig.json file where the includes: [] has the files that declare these augmentations.
@Skillz4Killz That is not the problem. The problem is the module name can change based on the import path (re-read the issue please!)
@Cretezy Perhaps I am seriously misunderstanding your issue, but I believe I had the same issue on my project. All I had to do was move imports to deps.ts file and augment the deps.ts file itself.
declare module "../../deps.ts" {
interface Member {
id: string;
joinedAt: number;
tag: string;
avatarURL: string;
mention: string;
}
}
All you need to do is import from a common source that you edit, such as deps.ts
@Skillz4Killz This is more for augmenting 3rd-party packages. For example:
In this case, package A can't augment package B, because the import tree is different:
---- Package A
------ Package B (B1)
---- Package B (B2)