Skip to content
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

Access global as a type #14052

Open
blakeembrey opened this issue Feb 13, 2017 · 9 comments
Open

Access global as a type #14052

blakeembrey opened this issue Feb 13, 2017 · 9 comments
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript

Comments

@blakeembrey
Copy link
Contributor

blakeembrey commented Feb 13, 2017

Since https://github.com/Microsoft/TypeScript/wiki/What%27s-new-in-TypeScript#augmenting-globalmodule-scope-from-modules it's been possible to augment the global from a module. However, in TypeScript definitions (such as dom.d.ts or node.d.ts) we're left to create our own "globals". This results in two issue:

  1. inconsistency with what is actually the global namespace
  2. requiring the declaration of global types multiple times in case it's used as a "real global" or from window. (browsers) or global. (node)

Instead of this, it'd be really nice to access TypeScript's global as a type. For instance, in dom.d.ts we could do:

declare var window: global

Or in node.d.ts:

declare var global: global

I couldn't see any previous issues, but it's partially related to things like #12902 - the difference though is that those issues seems to be tracking adding variables to the TypeScript global scope whereas this would be using the global scope as a type to define these variables themselves.

@yortus
Copy link
Contributor

yortus commented Feb 15, 2017

This is similar to #10050. Having a referenceable global type would do away with some painful duplication in declaration files. An additional scenario is sandboxed globals, described in #10050 (comment).

@mhegazy
Copy link
Contributor

mhegazy commented Feb 15, 2017

I would say this should be covered by #12902

@blakeembrey
Copy link
Contributor Author

@mhegazy Sorry, I read #12902 (comment) as a comment meaning it was really just a lib.d.ts change (e.g. declare var global: Window). If it is instead adding a real global type that mirrors TypeScript's "global" state and can be used in a type position for module authors I'm happy to close this issue.

@mhegazy
Copy link
Contributor

mhegazy commented Feb 15, 2017

@mhegazy Sorry, I read #12902 (comment) as a comment meaning it was really just a lib.d.ts change (e.g. declare var global: Window).

I think this is the feeling when we looked at this first. but I would expect users will have a similar request like yours. i would expect ppl wanting to do typeof global and be able to get things in declare global {...} blocks as well as declarations in the global scope.

If it is instead adding a real global type that mirrors TypeScript's "global" state and can be used in a type position for module authors I'm happy to close this issue.

I am fine lumping the two together, or keeping them separate. I would expect we need to do both if the proposal moves forward in the committee.

@nolakara
Copy link

We just ran in to this as well. We are handcoding typescript definitions for a legacy js library in the hope of pushing it to @types. We have multiple internal modules. One of the modules have a global variable X. And other have a variable X inside our common namespace Y. Now when the d.ts file of a third module want to refer the global X from inside our common namespace Y, there is no way right now. Any help on this?

@mhegazy
Copy link
Contributor

mhegazy commented Jan 12, 2018

@nolakara the need for a way to fully qualify a name has been discussed previously in #983. we then concluded that there was not a pressing need for this with modules and aliasing support. The recommendation for this case is to alias the global variable outside of your namespace and use the alias instead, e.g.:

import global_x = x;
namespace Y {
    export class x { }
   
   var local: x;
   var global: global_x;
}

@rjamesnw
Copy link

rjamesnw commented Jan 13, 2018

One way I resolved this was to create a layer from global to register globals. In namespace "A" I register global "x". "y". "z" properties (i.e. namespace A { export var x: ExpectedType; } A.x = x;), or even interfaces IX, IY, IZ, etc. In namespace A.B, or A.B.C, etc.,, I register all other types. This means I can always access A.x or A.IX (globals), or A.B.x (local types), etc. To make it easier I created a separate namespace for the globals, such as namespace AGlobals { export var globalx = x; } then you could do namespace A { export var x = AGlobals.globalx; }.

Example: https://goo.gl/JreGBg

var x = 1;
interface ISomeType { y: number; }

namespace AGlobals {
    export var globalx = x;
    export type globalISomeType = ISomeType;
}

namespace A {
    export var x = x;
    export type ISomeType = AGlobals.globalISomeType; // (OR use only AGlobals.globalISomeType instead)
    export namespace B {
        export var x = 2;
        export interface ISomeType { z: number; }
        var o: A.ISomeType; // (OR AGlobals.globalISomeType - depends on what you want)
        export function doSomething() {
            A.x = A.B.x;
            o.y = x;
        }
    }
}

There is another way to access globals using eval (or Function(...)) like this:

var x = 1; 
function test() { var x = 2; return eval.call(null, "x"); } 
test(); // returns 1 because eval is now called in the global scope.

Using new Function("return x;") also works instead of eval.call().

That assumes, of course, you are not trying to access a type (like an interface), and you will have to explicitly specify the expected type manually.

@weswigham
Copy link
Member

Random update: We pretty much know we want to do this (and talked about it when we added import types), we're just waiting for https://github.com/tc39/proposal-global (the proposal referenced in #12902) to stabilize with a name for the global-thing, so we can use the same name for the type lookup.

@ExE-Boss
Copy link
Contributor

This is now supported by using typeof globalThis in a type position.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

8 participants