-
Notifications
You must be signed in to change notification settings - Fork 12.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Global type references #983
Comments
how about a global modifier instead of reserving the name something like ``global::`: declare module M {
export class Error {
}
var x: global::Error;
}
var e: global::M.Error; |
|
We just as much need to solve the problem for external modules, so we'd need another special identifier that meant "the containing external module". |
👍 for a way to explicitly resolve global scope |
It is possible with a bit of _ab_use of function makeError(): Error {
return new Error("We've got a problem");
}
declare var GlobalError:Error;
module M {
export class Error {
}
export var x:typeof GlobalError = makeError(); // captured global type Error
} Related stackoverflow question: http://stackoverflow.com/a/27433864/390330 |
I think the fact that these kinds of ugly workarounds are necessary illustrates the need for a supported method of accessing the global scope. I could get behind either |
👍 for Reason: I don't like the confusion |
The main objection to :: is that it looks bad in a type position: |
Could we just use a leading . so .File or .Error, in the vein of PHP with \BuiltInClass. Alternatively, when in a browser context, use window.File, or window.Error, since whats were they are declared, rather than adding a new syntax. |
They/I would really like to support the same syntax for browser/node/anything else. Runtime shouldn't define TypeScript semantics (or as little as possible). I don't see a reason to not use |
I guess the problem with using window.X, global.X or any other . is that there is always the possibility of someone clobbering the namespace, with a parent module. Especially when these modules can be declared in another file. (Just tested this is the case). |
|
Does global still make sense to access a parent modules child? It is kind of foreign to typescript/javascript though. // Strings.d.ts
module Strings {
module Validator {
class Text {
}
}
}
// Vendor1String.ts
module Vendor {
module Strings {
module Validator {
class Markdown extends global::Strings.Validator.Text {
}
}
}
class Go {
runValidator(validator: global::Strings.Validator.Text) {
}
}
} |
Like the idea but what does 'global' resolve to? Could be interesting to be explicit about the 'global' being imported. module M {
import global from "@es6";
class Error {
}
var x: global.Error;
} |
global sounds like a useful way of controlling what /which |
Declined, at least for now. We're willing to revisit this if we see some more compelling cases where this is really necessary. Declaration file generation could be made marginally easier/more possible, but this doesn't seem to actually come up all that often. |
The decision to decline this is disappointing. The name shadowing problem is not limited to types, run time entities are shadowed as well. If a particular symbol can be reached from regular Javascript code, (IMHO) it should also be reachable from Typescript. |
Internal modules seem to cause more pain than joy. So I am 🆒 with this. |
Reclose and open a new one on global type augmentation problem |
What is the proposed solution for this right now in 1.8...? I have my own custom Touch class which I import under the name Touch. And I also need to access the global Touch type in the same file... |
@bartzy you're fundamentally out of luck because JavaScript has lexical scoping. There's nothing TypeScript can do to let you access an outer thing of the same name. |
Well, it must have some kind of solution besides just naming things differently.
But on 1.8 I get this error: |
this is in accordance with the ES6 spec. see https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#exporting-non-local-names-from-a-module for more details. To work around this, you need to have a local declaration, e.g: const localTouch = Touch;
export {Touch as BrowserTouch}; |
@mhegazy Thanks. But now when I import it, I get this error: This is my import line:
And this is
I also tried:
Thanks. |
@bartzy, I can not get a repro for your scenario. c:\test\983>type BrowserTypes.ts
const localTouch = Touch;
const localTouchEvent = TouchEvent;
export {localTouch as BrowserTouch, localTouchEvent as BrowserTouchEvent};
c:\test\983>type app.ts
import {BrowserTouch, BrowserTouchEvent} from './BrowserTypes';
c:\test\983>tsc --v
Version 1.8.7
c:\test\983>tsc --m commonjs app.ts
c:\test\983>echo %ERRORLEVEL%
0 |
@mhegazy, Try to use BrowserTouchEvent as a type to an argument in a function in app.ts. I get |
aah, it is not a type, it is a value.. see https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Declaration%20Merging.md#basic-concepts for more information.. What you want is to export both: const localTouchEvent = TouchEvent; // only value
type localTouchEvent = TouchEvent; // only type
export {localTouchEvent as BrowserTouchEvent}; // export both value and type ideally you would use |
Thanks, it works! I was under the impression that |
no, but types are not an |
Just checking - is this still an issue, or is there a solution to this yet? I used to have issues access types using some kind of fully qualified naming approach (as Anders suggested), but not sure where things stand now after much time has passed. |
Yeah, where are we at with this? Is there a way to reference a global that collides with something inside the namespace or no? |
As this problem
I known how to close this error, like this, but it'll export a global variant
Do this have a root namespace symbol, like PHP |
Polymer defines its own `Element` class, shadowing the standard global `Element` class. This means that references to `Element` within the `Polymer` namespace inadvertently reference `Polymer.Element`. Here we define an alias of the global `Element`, so that we can reference it from declarations within the `Polymer` namespace. See microsoft/TypeScript#983 for general discussion of this shadowing problem in TypeScript. Fixes #5074
Polymer defines its own `Element` class, shadowing the standard global `Element` class. This means that references to `Element` within the `Polymer` namespace inadvertently reference `Polymer.Element`. Here we define an alias of the global `Element`, so that we can reference it from declarations within the `Polymer` namespace. See microsoft/TypeScript#983 for general discussion of this shadowing problem in TypeScript. Fixes #5074
Polymer defines its own `Element` class, shadowing the standard global `Element` class. This means that references to `Element` within the `Polymer` namespace inadvertently reference `Polymer.Element`. Here we define an alias of the global `Element`, so that we can reference it from declarations within the `Polymer` namespace. See microsoft/TypeScript#983 for general discussion of this shadowing problem in TypeScript. Fixes #5074
Any progress on this front? |
When a type declaration in an inner module has the same name as a type declaration in an outer module, the outer declaration becomes inaccessible. Programmers can typically work around this, for example by deriving a type with an alternate name in the outer module or, with our latest changes, by declaring a type alias. However, such manual work-arounds are not a good option for code generation tools such as the .d.ts generation facility provided by the compiler. We really need a fool proof way to ensure a lookup starts at the global scope. Consider:
It is currently impossible to create a .d.ts file for the code above because there is no way to emit a type annotation for
x
that references the global interfaceError
.Node.js uses the name
global
for the global scope. We could consider supporting something similar in type names. Specifically, if a qualified type name starts with the identifierglobal
and if a lookup ofglobal
as a module name doesn't bind to anything (meaning the user didn't define aglobal
module), then we consider it a globally qualified name. For the example above we could then generate the following .d.ts file:If course, if the user defines their own
global
module we now have a problem again--but I think it is fine to just say you shouldn't do that. We could even consider making it an error, or allowing it only under a compiler switch.The text was updated successfully, but these errors were encountered: