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

Creating an interface with a symbol? #8099

Closed
benlesh opened this issue Apr 14, 2016 · 16 comments
Closed

Creating an interface with a symbol? #8099

benlesh opened this issue Apr 14, 2016 · 16 comments
Labels
Duplicate An existing issue was already created

Comments

@benlesh
Copy link

benlesh commented Apr 14, 2016

TypeScript Version:

1.7.5 / 1.8.0-beta / nightly (1.9.0-dev.20160217)

Code

// try augmenting the SymbolContructor to have some expected symbol on it.
// in RxJS5's case, it'll be the Symbol.observable symbol from the es-observable spec.
interface SymbolConstructor {
  observable: symbol;
}

interface Observablesque<T> {
  [Symbol.observable]: () => Subscribable<T>
}

or

// try importing some symbol reference (I get why this might not work)
import {$$observable} from './symbol/observable';

interface Observablesque<T> {
  [$$observable]: () => Subscribable<T>
}

Expected behavior:

I should be able to enforce types that have symbols on them, custom or otherwise.

Actual behavior:

I get really confused and go get myself a coffee.

@benlesh
Copy link
Author

benlesh commented Apr 14, 2016

Also, depending on the environment, that interface could be Symbol.observable or it could be '@@observable'.

@benlesh
Copy link
Author

benlesh commented Apr 14, 2016

What I"m looking at here are specifically two future built-ins: Symbol.observable and Symbol.asyncIterator.

@mhegazy
Copy link
Contributor

mhegazy commented Apr 14, 2016

The first one should work as if you have the Symbol definition.

The second one is a bit more involved. the issue is we do not know what the import points to at the time when we are building types, there is more discussion in: #2012
the issue is tracked by #5579

@david-driscoll
Copy link

Keep in mind, when imported through node definitions, the TypeScript compiler raises an error, because you cannot have ambient references as part of your source (/// <reference path=".../symbol.d.ts" />). Is there a way to augment ambient interfaces?

We had this at one point but it was causing errors so we backed it out.
ReactiveX/rxjs@d185ff8

@mhegazy
Copy link
Contributor

mhegazy commented Apr 14, 2016

why not declare global?

declare global {
   SymbolConstructor {
     observable: symbol;
   }
}

@benlesh
Copy link
Author

benlesh commented Apr 14, 2016

why not declare global?

Because I'm a better JavaScript developer than I am a TypeScript expert?

@DanielRosenwasser
Copy link
Member

Because I'm a better JavaScript developer than I am a TypeScript expert?

Good point @Blesh - I just filed this issue.

@david-driscoll
Copy link

because I didn't know that existed... I'll have to mess with that in a day or two. Thanks!

@benlesh
Copy link
Author

benlesh commented Apr 14, 2016

No dice with declare global.

@DanielRosenwasser
Copy link
Member

@Blesh can you elaborate what issues you're running into? This works for me.

foo.ts

export {};

declare global {
    interface SymbolConstructor {
        observable: symbol;
        asyncIterator: symbol;
    }
}

Symbol.observable;

tsconfig.json

{
    "compilerOptions": {
        "module": "commonjs",
        "target": "es6",
        "noImplicitAny": false,
        "sourceMap": false
    },
    "files": [
        "foo.ts"
    ]
}

@benlesh
Copy link
Author

benlesh commented Apr 14, 2016

@DanielRosenwasser

It complains at me:

TS2665: Module augmentation cannot introduce new names in the top level scope.

@DanielRosenwasser
Copy link
Member

SymbolConstructor will need to have been declared somewhere, so if you'll need to target ES6 or have a .d.ts file that declares it.

I believe if you're using nightlies, you could avoid targeting ES6 and use --lib es6.

@mhegazy
Copy link
Contributor

mhegazy commented Apr 14, 2016

logged #8102 for the error.

@benlesh
Copy link
Author

benlesh commented Apr 14, 2016

I believe if you're using nightlies, you could avoid targeting ES6 and use --lib es6.

What is this and how does it benefit us?

@robwormald
Copy link

@Blesh the nightly versions of TS let you do:

{
    "compilerOptions": {
        "module": "commonjs",
        "target": "es5",
        "noImplicitAny": false,
        "sourceMap": false,
        "outDir": "dist",
        "lib": ["es5", "es2015.promise", "dom"]
    },
    "files": [
        "src/main.ts"
   ]
}

rather than providing say, es6-shim external defs (the above config is what's needed to use rxjs, currently)

@DanielRosenwasser while Observable isn't part of the es6/es7 scope, its currently a stage1 proposal... does the lib option (amaaazing) provide a facility to add external lib.whatever files, or might y'all be open to having a lib.stage1.d.ts etc option as part of TS?

@mhegazy mhegazy added the Duplicate An existing issue was already created label Apr 19, 2016
@mhegazy
Copy link
Contributor

mhegazy commented Apr 19, 2016

closing in favor of #5579

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

5 participants