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
Issues with extending ObjectConstructor interface #3889
While this currently doesn't error in Playground, in 1.5.0-beta and release-1.5 branch, I get error TS2339: Property 'assign' does not exist on type 'ObjectConstructor' for the following:
@billccn interfaces always merge, even accross files. there is no such limitation. looks like you are talking about interfaces defined within a module, since modules have thier own scope, and interface with the same name as one in the global scope will not merge..
e.g.:
// global.d.tsinterfaceI{a: string}// myModule.tsimportdfrom"anotherModule";// This I is local to myModule and does not merge with the global"interfaceI{b: number;}
Ok, I tried several different variations because I got it "working" accidentally and I realise the problem. Now I don't know if it is as designed or not (it is very confusing from a developer though).
When you have a top-level export, your file is a module, which means all declarations are introduced at the module scope rather than the global scope. This means that interface ObjectConstructor declares a new type ObjectConstructor (at the module scope) rather than merging with the ObjectConstructor type from the global scope.
This is intentional because otherwise there wouldn't be any way to make a new interface local to your module that had the same name as a global type.
Thanks. I figured it was intentional, but obviously it is rather confusing, especially when not having a "choice" about accessing globally scoped namespaces at the implementation level. I assume there are no language semantics to denote that I am referring to the global namespace? Therefore, the only way to extend it is as @billccn suggests (and Mohamed Hegazy (@mhegazy) implies) by declaring in a non-module, like a project .d.ts.
Bryan Forbes (@bryanforbes) thanks for the effective workaround. #983 being re-opened would also address the "limitation" I am perceiving so I will close in lieu of that.
Guys, sorry to comment in this zombie thread but there is weird stuff happening.
Declaring a following definition file does nothing and typescript does not recognise the polyfill:
i would assume that the file polyfills.d.ts has a top level import or export, this turns it into a module. modules have their own scope, an this this ObjectConstructor is not really the ObjectConstructor but rather a local interface with the same name that shadows the global declaration.
using the declare global syntax, you are bypassing the scoping of the module and placing the declaration explicitly in the global scope, and this it merges with the intended ObjectConstructor declaration and you get the desired behavior.
Activity
qc00 commentedon Jul 16, 2015
This is due to some limitations in definition merging where interfaces declared in
d.tsfiles do not merge with "normal" ones declared in.tscode.Your example would have worked if you could say
but you can't do
declareoninterface.The only solution is to move the
interfacebit into its own.d.tsand///<refereceit from your code.mhegazy commentedon Jul 16, 2015
@billccn interfaces always merge, even accross files. there is no such limitation. looks like you are talking about interfaces defined within a module, since modules have thier own scope, and interface with the same name as one in the global scope will not merge..
e.g.:
mhegazy commentedon Jul 16, 2015
Kitson Kelly (@kitsonk) the sample you provided works fine for me on latest. can you provide more details?
kitsonk commentedon Jul 16, 2015
Ok, I tried several different variations because I got it "working" accidentally and I realise the problem. Now I don't know if it is as designed or not (it is very confusing from a developer though).
The following works:
The following gives
Property 'assign' does not exist on type 'ObjectConstructor':Obviously it has to do with modules and namespacing, but I will admit I am confused.
RyanCavanaugh commentedon Jul 16, 2015
When you have a top-level
export, your file is a module, which means all declarations are introduced at the module scope rather than the global scope. This means thatinterface ObjectConstructordeclares a new typeObjectConstructor(at the module scope) rather than merging with theObjectConstructortype from the global scope.This is intentional because otherwise there wouldn't be any way to make a new interface local to your module that had the same name as a global type.
kitsonk commentedon Jul 16, 2015
Thanks. I figured it was intentional, but obviously it is rather confusing, especially when not having a "choice" about accessing globally scoped namespaces at the implementation level. I assume there are no language semantics to denote that I am referring to the global namespace? Therefore, the only way to extend it is as @billccn suggests (and Mohamed Hegazy (@mhegazy) implies) by declaring in a non-module, like a project
.d.ts.RyanCavanaugh commentedon Jul 16, 2015
Correct. Some related discussion in #3857 and #983
bryanforbes commentedon Jul 16, 2015
Kitson Kelly (@kitsonk) Given what Ryan Cavanaugh (@RyanCavanaugh) explained, could you do something like this?
kitsonk commentedon Jul 16, 2015
Bryan Forbes (@bryanforbes) thanks for the effective workaround. #983 being re-opened would also address the "limitation" I am perceiving so I will close in lieu of that.
tomitrescak commentedon Aug 23, 2016
Guys, sorry to comment in this zombie thread but there is weird stuff happening.
Declaring a following definition file does nothing and typescript does not recognise the polyfill:
but declaring it inside global, using module augmentation works
Any idea why this is?
mhegazy commentedon Aug 24, 2016
i would assume that the file
polyfills.d.tshas a top level import or export, this turns it into a module. modules have their own scope, an this thisObjectConstructoris not really theObjectConstructorbut rather a local interface with the same name that shadows the global declaration.using the
declare globalsyntax, you are bypassing the scoping of the module and placing the declaration explicitly in the global scope, and this it merges with the intendedObjectConstructordeclaration and you get the desired behavior.