Skip to content

Fails to get contextual type for string literal in array #19837

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

Closed
ghost opened this issue Nov 8, 2017 · 2 comments · Fixed by #19966
Closed

Fails to get contextual type for string literal in array #19837

ghost opened this issue Nov 8, 2017 · 2 comments · Fixed by #19966
Assignees
Labels
Bug A bug in TypeScript Fixed A PR has been merged for this issue High Priority

Comments

@ghost
Copy link

ghost commented Nov 8, 2017

TypeScript Version: 2.7.0-dev.20171108

Code

const x: 'a' | 'a'[] = ['a'];

Expected behavior:

No error.

Actual behavior:

src/a.ts(1,7): error TS2322: Type 'string[]' is not assignable to type '"a" | "a"[]'.
  Type 'string[]' is not assignable to type '"a"[]'.
    Type 'string' is not assignable to type '"a"'.

Was broken by #19733 -- verified by testing with its merge commit and with the previous commit. @weswigham
Detected by running DefinitelyTyped tests.

@ghost ghost added the Bug A bug in TypeScript label Nov 8, 2017
@mhegazy
Copy link
Contributor

mhegazy commented Nov 8, 2017

@weswigham can you please take a look.

@mhegazy mhegazy added this to the TypeScript 2.7 milestone Nov 8, 2017
@weswigham
Copy link
Member

weswigham commented Nov 8, 2017

So this is definitely fixed by #19587 (so that's good, there's already a fix up), however I'm unsure as to how #19733 would be the change that broke it... I could easily see how #17668 could break it, though (and I just doubled checked, it is broken at d6436f1 (the master commit prior to #19733's master commit), so #19733 is not the culprit). Yeah, definitely #17668.

Long story short, this actually should never have worked under our current contextual typing rules, if not for a bug in our lack-of-handling-unions-correctly (which made it so that we never saw the index signature on "a"). "a" has an index signature of type string, while 'a'[] has an index signature type of 'a'. 'a' | string is reduced to string, and then we no longer have a literal contextual type. This wasn't triggered before because we never got the apparent type of string literals within unions (which was a bug).

We could do one of a few things:

  • Work on merging More prolific literal types #19587 a bit faster to make it so the literalness of the contextual type no longer matters, only its domain
  • Change the apparent type of string literals to not have an indexer, but instead have properties corresponding to the codepoint in the string (most accurate, likely an improvement in other ways, like having a strongly typed ("foo")[0]) (Which I just opened String literal apparent types with specific member types #19846 with so we can talk about it, even if not for this issue, but for its other benefits)
  • Special-case string literals in getApparentTypeOfContextualType so that we don't actually get their apparent type when they are nested within a union (mimicking old buggy behavior)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Bug A bug in TypeScript Fixed A PR has been merged for this issue High Priority
Projects
None yet
2 participants