TypeScript: Can not declaration merging for default exported class
TypeScript Version: 2.1.5
Code
// A *self-contained* demonstration of the problem follows...
// ===== file Foo.ts =====
export default class Foo {
hello() {
console.log('Foo');
}
}
// ===== file Bar.ts =====
import Foo from './Foo';
declare module './Foo' {
interface Foo {
add(x, y);
}
}
// ERROR: 'add' does not exist in type Foo.
Foo.prototype.add = function (x, y) { return x + y; };
let f = new Foo();
f.hello();
f.add(3, 4); // ERROR: 'add' does not exist in type Foo.
Expected behavior: If the class Foo is exported without default in file Foo.ts, and then import {Foo} from ‘./Foo’, it works correctly as example in doc http://www.typescriptlang.org/docs/handbook/declaration-merging.html
Hope import Foo same as import {Foo} behaviors.
Actual behavior: ERROR message showed.
About this issue
- Original URL
- State: open
- Created 7 years ago
- Reactions: 47
- Comments: 22 (5 by maintainers)
Is there a way for augmenting a module exported with
export =though? I wasn’t able to get it working.i.e
knex.d.ts
file.ts
You can only augment “exported” declarations. Class
Foois exported asdefault, and not asFoo. so the nameFoodoes not exist outside the module.It just happens that
defaultis a reserved word, and can not used as an interface declaration name.The TS compiler needs to allow
export { Foo as default}in module augmentation.It seems to be working with the following convoluted setup:
some-library-you-cant-modify/Foo.ts
my-library/typings/Foo.ts
my-library/typings/Foo.d.ts
my-library/consumer.ts
You’ll have to add your
Foo.d.tsfile in my-library/tsconfig.json:I wanted to point out that I think export-assigned (
export =) classes have the same problem as default-exported classes of not being augmentable. There have been two questions (1, 2) about this on Stack Overflow in the past week. Given the lack of action on this bug, I didn’t think it would be helpful to file a separate bug for export-assigned classes.Any time you export a default, you’re effectively creating a new name - so if you want to rename something globally, you have to search/replace for it, and track all the imports that re-export it. But by sticking to named exports, various refactoring tools can follow that name all the way through the code base 👍
On Fri, Sep 29, 2017 at 12:57 PM Joe Lapp notifications@github.com wrote:
defaultis a keyword of JS. By the way, you can export a new variable temporarily.node_modules -> knex.ts
custom knex.ts
@m93a I don’t think your scenario has anything to do with this issue since you aren’t using a class. Your idea 3 works if I
exporttheMarkdownItStaticinterface in the first file. It isn’t exported by default since the module has a default export expression (see this post), and it has to be exported in order to be augmented.I’ve stopped using default exports in most cases - partly due to this, and also to make refactoring less painful
On Thu, Sep 28, 2017, 10:49 Joe Lapp notifications@github.com wrote:
Thanks @nevir. Is the issue with defaults and refactoring that a class is less likely to have a single name across the entire application? Is that also an argument for not exporting functions directly but instead making stateless functions static methods on exported classes?