Repository navigation
Declarations and "Exported variable 'XXX' has or is using name 'YYY' from external module "ZZZ" but cannot be named." #24666
Description
Activity
I can't find the comment I made on a workaround anymore. It was on a similar issue but even worse, because when this happens with generic types, you generally find yourself losing out on type inference.
The workaround was to use the imported type with a dummy variable if it's an interface or type alias.
If it's a class, you can get away with
NameOfClass;as a statement and it counts as a usage.With interfaces and the like,
import {SomeGenericInterface} from "thing"; const dummy : SomeGenericInterface<any, any, any>|undefined = undefined; dummy;
I'm on my phone so I'm not sure if I've described it properly.
This way, type inference still works and you've imported and used the type. but it's extremely ugly and hacky. And, in general, you don't know what needs to be imported and used this way until you want to compile the code...
I wish there was a way for it to automatically import during the compile phase because this workaround I use has given me no problems.
It's just repeatedly,
- Run tsc
- See that error?
- Import type
- Create dummy variable of imported type union undefined
- GOTO 1
So, I've got it down to an algorithm but you might end up needing to do this for hundreds of files, to compile. And you don't need to do this at all with
--noEmitor to run with ts-nodeReacted by Ben IlegboduThanks, AnyhowStep - that's very similar to what I do at the moment too:
((_1?: StyledComponentClass<any, any>, _2?: typeof React) => 0)();
🤢
I've got dozens of files that start this way.
Reacted by AnyhowStepI like your way better, actually.
I just tried something and it seemed to work (I haven't exhaustively tested this so I'm not 100% sure)
Just do,
import * as package1 from "some-package-1"; import * as package2 from "some-package-2"; package1; package2;
Assuming
package1andpackage2contain interfaces/type aliases/classes, that you need for emitting. This helps if there are many interfaces/type aliases/classes in a package that are needed.Doesn't help so much if you only need the one type.
- addedBugA bug in TypeScriptA bug in TypeScriptDomain: Declaration EmitThe issue relates to the emission of d.ts filesThe issue relates to the emission of d.ts files
on Jun 13, 2018 Jamie Winder (@jamiewinder) Thanks for the report! Apologies - looks like our visibility checking logic in declaration emit didn't handle things aliased via
export=correctly (as is the case for theReactdeclaration file), so is exhibiting the old behavior for now. I should have a fix up tomorrow.- addedFixedA PR has been merged for this issueA PR has been merged for this issue
on Jul 5, 2018 - locked as resolved and limited conversation to collaborators
on Oct 21, 2025
I was pleased to see #9944 had been closed with what looked like a feature of 2.9 'fixing' the issue. However, it still doesn't seem to be working as I'd expect. Take this example:
With a normal TypeScript project, using the tsconfig default except enabling
declarations. I get three errors:The obvious solution seems to be importing the types involved:
Which would be fine, I suppose (though I don't see why it is necessary..?) but this doesn't work with
noUnusedLocalsas you get more errors:... However you can work around that by explicitly using the types, but even with this basic example it gets absurdly verbose:
What is the recommended solution / workaround to this?