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

Use SingletonStrT, SingletonNumT, SingletonBoolT in case of const literal declarations #7607

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

goodmind
Copy link
Contributor

@goodmind goodmind commented Apr 2, 2019

Revived #4175
Fixes #2639

@goodmind
Copy link
Contributor Author

goodmind commented Apr 2, 2019

@mrkev probably

@goodmind goodmind changed the title Use SingletonStrT in case of const literal declarations Use SingletonStrT, SingletonNumT, SingletonBoolT in case of const literal declarations Apr 3, 2019
@mrkev
Copy link
Contributor

mrkev commented Apr 4, 2019

Let's check this out

Copy link
Contributor

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

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

@mrkev has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@mrkev
Copy link
Contributor

mrkev commented Apr 5, 2019

I'm seeing issues similar to this:

const foo = {
  bar: 10,
  baz(x: number) {
    foo.bar = x; // Error, number incompatible with number
  },
}

Also tagging @nmote so this PR get some visibility from someone in the team.

@goodmind
Copy link
Contributor Author

goodmind commented Apr 5, 2019

@mrkev I'm not sure how this is related, because it only uses affects const primitive literals, not object literals properties, I'll check

@goodmind
Copy link
Contributor Author

goodmind commented Apr 5, 2019

Maybe you mean something like this

const bar = 10;
const foo = {
  bar,
  baz(x: number) {
    foo.bar = x; // Cannot assign `x` to `foo.bar` because  number [1] is incompatible with  number
  },
}

@goodmind
Copy link
Contributor Author

goodmind commented Apr 5, 2019

Yeah, totally bug, I should replace reason of DefT

@goodmind
Copy link
Contributor Author

goodmind commented Apr 5, 2019

Now this errors correctly

Cannot assign `x` to `foo.bar` because  number [1] is incompatible with  number literal `10` [2]

@goodmind
Copy link
Contributor Author

goodmind commented Apr 5, 2019

@mrkev do you think this shouldn't error at all and property type should be widened to number?

@goodmind
Copy link
Contributor Author

goodmind commented Apr 5, 2019

It's interesting that in TypeScript if type is inferred then it's widened, but if it's specified by user it isn't

const str = 'string';
const num = 200;
const bool = true;
const str1: 'string' = 'string';
const num1: 200 = 200;
const bool1: true = true;

const foo = {
  str,
  num,
  bool,
  str1,
  num1,
  bool1,
  method() {
    foo.str = 'any string' // no error
    foo.num = 300 // no error
    foo.bool = false // no error
    foo.str1 = 'any string' // error
    foo.num1 = 300 // error
    foo.bool1 = false // error
  }
}

@goodmind
Copy link
Contributor Author

goodmind commented Apr 5, 2019

@goodmind
Copy link
Contributor Author

goodmind commented Apr 8, 2019

I'm now not sure what the cases for this are, refinements and switch seems to work fine with just regular const

@mrkev
Copy link
Contributor

mrkev commented Apr 11, 2019

I think it depends if this code is bug or not
https://flow.org/try/#0MYewdgzgLgBAYgeQQLhgIkQtMC87NoDcAUMADYCGEEMAQhQE4wDexMMUAngA4Cmu8JCXYALXmTIgAFAEoWbdhxEBLCADoufAWjDLgvIgoC+xE6EiwARowGt2m3qkwAaBWInS5dxdYYae-Hg6egbCMCZGhEA

I think what typescript does falls in the right direction, and would personally err on the side of widening, though this is a good question to bring up on the Discord channel for discussion IMO.

Copy link
Contributor

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

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

@mrkev has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@goodmind
Copy link
Contributor Author

So this is stalled because we didn't found out how to widen literals to string in mutable locations. This would definitely need another kind of SingletonStrT, and more handling related to variance?

@goodmind
Copy link
Contributor Author

goodmind commented Jul 23, 2019

@mrkev what you think about implementing const assertions instead?
https://devblogs.microsoft.com/typescript/announcing-typescript-3-4/#const-assertions

EDIT: nvm, same problems with inference
https://flow.org/try/#0DYUwLgBAthC8EAoDaBGANBATBgzAXQC4JUNsJ8BKAKCpnhSqA

The only working thing is fixing typeof directly, since this is most used case of getting literal type from string

@goodmind
Copy link
Contributor Author

Related issue #7961

@goodmind goodmind mentioned this pull request Jul 26, 2019
@goodmind goodmind added the Stalled Issues and PRs that are stalled. label Jul 27, 2019
@goodmind goodmind added Blocked and removed Stalled Issues and PRs that are stalled. labels Aug 20, 2019
@goodmind
Copy link
Contributor Author

@mrkev

declare var foo: {+a: 'str'}
declare var foo_a: 'str';

const bar = {
  a: foo.a,
  b: foo_a,
  method() {
    bar.b = 'bar' // error
    bar.a = 'bar' // no error
  }
}

https://flow.org/try/#0CYUwxgNghgTiAEA3W8BmB7dAueBvA1FDgOQDOALjMQL4BQoksCyMamA+kfGZcQNy1aYdADsK8AEYoAvHlrx4XDOgB0UADTzJOZZ00KAtiHIALdMAAUASjkKFUmConxZxB8S33Yal93da6aiA

Kinda strange, how can we get bar.b work the same as bar.a?

@goodmind goodmind removed the Blocked label Aug 20, 2019
@goodmind
Copy link
Contributor Author

goodmind commented Aug 20, 2019

@mrkev I solved this problem, should I add more tests?

@goodmind
Copy link
Contributor Author

goodmind commented Aug 20, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

typeof string literal
3 participants