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

Expunge the concept of well-known symbols from the checker #24738

Closed
wants to merge 10 commits into from

Conversation

weswigham
Copy link
Member

@weswigham weswigham commented Jun 7, 2018

Interestingly, there is some fallout here in some odd places:

  • First of all, some small changes needed to occur to replicate old behavior. Right now, a computed name of type any produces a number index signature. With this change, we make a string index signature instead (it's more broad and closer to correct).
  • Additionally, late-bound members weren't issuing duplicate declaration errors. With this change, they should.
  • There's also a fourslash test changes due to the lib in fourslash not-actually-having-symbols (I looked into fixing it to use the built lib, it requires changing a bunch of tests, don't wanna do that here), so the test relied on the old behavior of well-known symbols always "resolving" uniquely, regardless of weather or not they were actually defined.
  • Lastly, some emit changes - specifically, where previously we'd elide Symbol.iterator when it appeared as a property name (and assume that the expression had no sideffects), now we retain and emit it (and potentially cache it), as we generally do not assume property access expressions are safe to elide or copy.

Fixes #24622

An important implementation note: As we discussed in person, Inside the checker, if we see members of the global SymbolConstructor of type symbol, we also assume you meant to say unique symbol. In this way, we retain compataibility with older libs or definition files (even as they update), which is how this can build (at all), given node is shimming Symbol.iterator as a symbol.

const name = hasLateBindableName(decl) && resolveEntityName(decl.name.expression, SymbolFlags.Value);
if (name && context.tracker.trackSymbol) {
context.tracker.trackSymbol(name, saveEnclosingDeclaration, SymbolFlags.Value);
if (hasLateBindableName(decl)) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a copy of the primary change from #24668 - it's required to make the symbols get looked up correctly.

@weswigham weswigham closed this Jun 7, 2018
@weswigham weswigham reopened this Jun 7, 2018
@weswigham
Copy link
Member Author

weswigham commented Jun 7, 2018

Huh. These changes seem pretty innocuous, but the build of run.js (the tests) runs out of memory on node6 (and only on node6). During sourcemap emit no less, so very late in the process. @rbuckton can you think of anything offhand we'd be doing where the memory consumption of node6 vs node8 would differ enough to crash the process?

@weswigham weswigham closed this Jun 7, 2018
@weswigham weswigham reopened this Jun 7, 2018
@mhegazy mhegazy requested a review from rbuckton June 7, 2018 19:59
@RyanCavanaugh
Copy link
Member

@weswigham Ron's sourcemap rewrite should be going in soon so that will hopefully fix the OOM issues you're getting here

@weswigham
Copy link
Member Author

A merge with master from two months ago shows that we'd already resolved the issue. CI on this PR is green, though it's probably out of date again.

@andrewbranch
Copy link
Member

Also fixes #31253

@ExE-Boss
Copy link
Contributor

ExE-Boss commented Jan 3, 2020

This needs some serious rebasing.

Also fixes #27525 and #21603.

@ExE-Boss
Copy link
Contributor

This will also fix #36468

@KilianKilmister
Copy link

any update on this?

@weswigham
Copy link
Member Author

@rbuckton do we have an appetite for looking into this again? It looks like a number of things are getting dupe'd to it. IIRC we held off on it long ago so lib references could be a thing in node, to potentially remove the need for the global SymbolConstructor-symbol-as-unique symbol workaround.

@justingrant
Copy link
Contributor

FWIW, this PR would also probably fix immerjs/immer#710.

@DanielRosenwasser
Copy link
Member

I'd like to bring this back to our focus. I recently spoke to @benlesh about RxJS and how the library leans on Symbol.observable existing.

So just to start, imagine an augmentation like

interface SymbolConstructor {
    observable: symbol;
}

This is inspired by the existing declarations; however, the symbol-observable library re-exports Symbol.observable. If the declaration file contains code like

const symbolObservable: typeof Symbol.observable;
export default symbolObservable;

that appears to any other code as just symbol.

Trying to switch over to a unique symbol like so

interface SymbolConstructor {
    observable: unique symbol;
//              ^^^^^^
}

won't necessarily work because other libraries have also defined it as symbol

interface SymbolConstructor {
    observable: symbol;
}

interface SymbolConstructor {
    observable: unique symbol;
//  ~~~~~~~~~~
// Subsequent property declarations must have the same type.  Property 'observable' must be of type 'unique symbol', but here has type 'symbol'.
}

@benlesh
Copy link

benlesh commented Jan 28, 2021

I would like to note that:

  1. I'm sorry. haha
  2. I inherited symbol-observable which was always written this way, while it was in wide use.
  3. This stuff is hard.

Another point is that we support IE, which doesn't have Symbol, so we're actually tricking the type system here a bit. Sometimes we get "@@observable" instead, because there's no Symbol. I'll admit it's not ideal, though.

@weswigham
Copy link
Member Author

#42543 Now supersedes this as an updated version for 2021 - large parts are the same (and the result certainly is), but some of the implementation is different.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Author: Team Experiment A fork with an experimental idea which might not make it into master
Projects
None yet
Development

Successfully merging this pull request may close these issues.

keyof does not include well known symbols
10 participants