You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Experimental (deprecated) decorators are included by default #63346
The old experimental decorators have (to my knowledge) always been opt-in, which means the types for those decorators are wrong by default. Now we have new decorators which are available by default, but still the old decorator types exist.
My project is using esnext lib, but it doesn't matter which version you use because they all end up including the legacy types.
In order to make my life "easier" I have defined a handful of types describing the actual function signatures of the new decorators, but my ClassDecorator (in my own types.d.ts) and the legacy decorator types are conflicting.
// adding this import fixes the type error, but the import line itself becomes an error// > File '[snip]/types.d.ts' is not a module.// import type {ClassDecorator} from './types';constfoo=Symbol('foo');constbar=Symbol('bar');typeFoobarMixin={[foo]: number;[bar](): string;};functionfoobarMixin<ThisextendsFoobarMixin,Classextendsabstractnew(...args: any)=>This=abstractnew(
...args: any)=>This,>(): ClassDecorator<This,Class>{return(target: Class,_context: ClassDecoratorContext<Class>)=>{target.prototype[foo]=42;target.prototype[bar]=function(){return'hello';};};}interfaceThingextendsFoobarMixin{}
@foobarMixin()classThing{}console.log(newThing()[foo]);console.log(newThing()[bar]());
🤖 Thank you for your issue! I've done some analysis to help get you started. This response is automatically generated; feel free to 👍 or 👎 this comment according to its usefulness.
This is not an issue about missing an export. The *.d.ts files are included by default as globals. Correct me if I'm wrong but I shouldn't to import anything from a .d.ts.
Adding an export does not address my claim that "legacy decorators should not be included by default" so I'm afraid you've missed the point of this ticket.
All the other types defined in .d.ts files work fine without any imports, the issue is with this particular type name conflict.
What I'm saying here is that you're trying to work from an invariant (any global type name should be available for usercode use) that doesn't exist, nor could exist (you can't declare "your own" Array, for example). The recommended approach for all usercode is to have your types in modules (i.e. export them), which don't have global conflicts.
Wouldn't the "invariant that does not / could not exist" be the legacy decorator types, since they do not reflect the concrete implementation provided by the compiler?
I agree that types should be in modules for my own code, but the behavior I'm trying to capture is related to the compiler itself, its applicability is not restricted to a subset of modules. The decorator syntax is intrinsically ambient. The "xyzDecorator" types I'm trying to define are useful type-hints for defining decorators (or rather, decorator-returning functions).
I'm not sure how the Array example is relevant here since I'm not trying to redefine any concrete types.
Decorators work with implementation X.
The built-in types are defined for decorators that work with implementation Y.
Since X !== Y, the built-in types are not useful. Not only are they not useful, they're preventing developers from defining types that correctly describe implementation X in a way that makes sense for an ambient language feature.
The point of the lib.d.ts family of files are to describe the environment in which we're programming. The legacy types don't do that.
I'm sorry if I'm coming off as stubborn, I really don't understand why there's a desire to keep the inaccurate type definitions. Even if we were to forget about my particular naming conflict issue (and I were to start using modular types), the existing types would still be inaccurate and misleading.
Activity
RyanCavanaugh commentedon Apr 6, 2026
🤖 Thank you for your issue! I've done some analysis to help get you started. This response is automatically generated; feel free to 👍 or 👎 this comment according to its usefulness.
Similar Issues
Here are the most similar issues I found
If your issue is a duplicate of one of these, feel free to close this issue. Otherwise, no action is needed.
RyanCavanaugh commentedon Apr 7, 2026
The error message means what it says; you are missing the
exportmodifier on your type aliastypescript-bot commentedon Apr 10, 2026
This issue has been marked as "Question" and has seen no recent activity. It has been automatically closed for house-keeping purposes.
OldStarchy commentedon Apr 16, 2026
This is not an issue about missing an export. The
*.d.tsfiles are included by default as globals. Correct me if I'm wrong but I shouldn't to import anything from a.d.ts.Adding an export does not address my claim that "legacy decorators should not be included by default" so I'm afraid you've missed the point of this ticket.
All the other types defined in
.d.tsfiles work fine without any imports, the issue is with this particular type name conflict.OldStarchy commentedon Apr 16, 2026
Of the other issues you listed, #29828 is the closest match, though I'm suggesting that types need removing, rather than "fixing".
Replacing the legacy decorator types with the new ones could just invert the problem for projects that do rely on the legacy decorator syntax.
fix: remove unused legacy decorator types
RyanCavanaugh commentedon Apr 16, 2026
What I'm saying here is that you're trying to work from an invariant (any global type name should be available for usercode use) that doesn't exist, nor could exist (you can't declare "your own"
Array, for example). The recommended approach for all usercode is to have your types in modules (i.e.exportthem), which don't have global conflicts.OldStarchy commentedon Apr 19, 2026
Wouldn't the "invariant that does not / could not exist" be the legacy decorator types, since they do not reflect the concrete implementation provided by the compiler?
I agree that types should be in modules for my own code, but the behavior I'm trying to capture is related to the compiler itself, its applicability is not restricted to a subset of modules. The decorator syntax is intrinsically ambient. The "xyzDecorator" types I'm trying to define are useful type-hints for defining decorators (or rather, decorator-returning functions).
I'm not sure how the
Arrayexample is relevant here since I'm not trying to redefine any concrete types.Decorators work with implementation X.
The built-in types are defined for decorators that work with implementation Y.
Since X !== Y, the built-in types are not useful. Not only are they not useful, they're preventing developers from defining types that correctly describe implementation X in a way that makes sense for an ambient language feature.
The point of the lib.d.ts family of files are to describe the environment in which we're programming. The legacy types don't do that.
I'm sorry if I'm coming off as stubborn, I really don't understand why there's a desire to keep the inaccurate type definitions. Even if we were to forget about my particular naming conflict issue (and I were to start using modular types), the existing types would still be inaccurate and misleading.