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

[Bug]: Typescript plugin fails on named tuple positions where the name is a reserved word in JS #13702

Closed
1 task
happycollision opened this issue Aug 24, 2021 · 14 comments · Fixed by #15423
Closed
1 task
Assignees
Labels
area: typescript good first issue i: bug outdated A closed issue/PR that is archived due to age. Recommended to make a new issue pkg: parser

Comments

@happycollision
Copy link

happycollision commented Aug 24, 2021

💻

  • Would you like to work on a fix?

How are you using Babel?

babel-loader (webpack)

Input code

type FuncWithDescription = [
  function: (...args: any[]) => any,
  string: string
]

https://babeljs.io/repl#?browsers=defaults&build=&builtIns=false&corejs=3.6&spec=false&loose=false&code_lz=C4TwDgpgBAYgrgOwMYHUCWwAWARCBnJAJzTGDQHsEoBeKAbQCgooAzRJMygLigAoA6QQENCAczw8hCEHQC6AShoA-KFJAAaJlDzBiCUTx17RDWQwZJKO1gnRZcBYqQoIJsdnZz4iJTgjk09FrMdLwAHlwIcAC2AEYQhIrUKmHqUABEhBDAcIRUWNBRcQnpsprMIeGRMfGEaSDVxYnKUGEAVBoZ0XAANmRgPSBQBVBFtXilpkA&debug=false&forceAllTransforms=false&shippedProposals=false&circleciRepo=&evaluate=false&fileSize=false&timeTravel=false&sourceType=module&lineWrap=true&presets=env%2Creact%2Cstage-2%2Ctypescript&prettier=false&targets=&version=7.15.3&externalPlugins=&assumptions=%7B%7D

Configuration file name

No response

Configuration

See REPL link

Current and expected behavior

Current

It throws at line 2: /repl.tsx: Unexpected token (2:2)
If you rename function to fn, then
it throws at line 3: Tuple members must be labeled with a simple identifier. (3:2)

Expected

It does not throw an error on either line. Why would I expect this? Because TS is totally fine with this same code: https://www.typescriptlang.org/play?ts=4.0.2#code/C4TwDgpgBAYgrgOwMYHUCWwAWARCBnJAJzTGDQHsEoBeKAbQFgAoKVqAM0STMoC4oAFADoRAQ0IBzPP1EIQdALoBKagD4oskABpmbKHmDEEE-gaMTmC5sySUDHBOiy4CxUhQTTYXJznxESHgRFGnpdNjoBAA9eBDgAWwAjCEIlGnUorSgAIkIIYDhCKixoOKSU7IUdFgjo2ITkwiyQevLU9KgogCptHPi4ABsyMAGQKBKoMsa8SssgA

Environment

See REPL link for env details

Possible solution

There are two ways to fix this problem, in my opinion

Option 1: Updated docs, and better error messages

Indicate in the docs (just like with other caveats) that there are certain tokens that are not acceptable for named tuple positions.

Then, ensure that the errors thrown in my example above clearly state this problem and/or reference the newly updated docs. I think the second error (Tuple members must be labeled with a simple identifier.) is possibly acknowledging this discrepancy, but it is not clear to me that the error is a known caveat vs an actual TS syntax issue. (The first error thrown against the word function, though, is quite vague.)

Option 2: Update the TypeScript plugin to handle these names

I do not know how many words fail in the Babel plugin, and yet succeed in TS. I do know that the following are in the list:

  • function
  • string
  • number

Additional context

No response

@babel-bot
Copy link
Collaborator

Hey @happycollision! We really appreciate you taking the time to report an issue. The collaborators on this project attempt to help as many people as possible, but we're a limited number of volunteers, so it's possible this won't be addressed swiftly.

If you need any help, or just have general Babel or JavaScript questions, we have a vibrant Slack community that typically always has someone willing to help. You can sign-up here for an invite."

@nicolo-ribaudo
Copy link
Member

nicolo-ribaudo commented Aug 29, 2021

Thanks for the bug report!

The problem is in the tsParseTupleElementType parser function:

tsParseTupleElementType(): N.TsType | N.TsNamedTupleMember {
// parses `...TsType[]`
const { start: startPos, startLoc } = this.state;
const rest = this.eat(tt.ellipsis);
let type = this.tsParseType();
const optional = this.eat(tt.question);
const labeled = this.eat(tt.colon);
if (labeled) {

Keywords are not valid types (i.e. type X = [function] is invalid), so the tsParseType() call at line 888 fails. We should be able to fix it by:

  1. Checking if the current token is a keyword (if this.state.type.keyword is true)
  2. If it is not a keyword, then we can keep the current logic.
  3. Otherwise, we should:
    1. Parse the label as an identifier, using this.parseIdentifier(/* allow keywords */ true).
    2. Consume a : token, using this.expect(tt.colon).
    3. Finish parsing the tuple element, as in
    labeledNode.elementType = this.tsParseType();
    type = this.finishNode(labeledNode, "TSNamedTupleMember");

If anyone wants to help fixing this bug and it is the first time that you contribute to Babel, follow these steps: (you need to have make and yarn available on your machine)

  1. Write a comment here to let other possible contributors know that you are working on this bug.
  2. Fork the repo
  3. Run git clone https://github.com/<YOUR_USERNAME>/babel.git && cd babel
  4. Run yarn && make bootstrap
  5. Wait ⏳
  6. Run make watch (or make build whenever you change a file)
  7. Add a test (only input.ts; output.json will be automatically generated) in https://github.com/babel/babel/tree/main/packages/babel-parser/test/fixtures/typescript/types
    • We need a test for the valid case (the example in the bug report) and for the invalid case [function].
  8. Update the code!
  9. yarn jest parser to run the tests
    • If some test outputs don't match but the new results are correct, you can delete the bad output.js files and run the tests again
    • If you prefer, you can run OVERWRITE=true yarn jest parser and they will be automatically updated.
    • New parser tests sometimes fail: don't worry, run yarn jest parser again after that
  10. If it is working, run make test to run all the tests
  11. Run git push and open a PR!

@ChaitanyaGadodia
Copy link

Hi! Can I pick this bug?

@nicolo-ribaudo
Copy link
Member

nicolo-ribaudo commented Aug 29, 2021

Sure, it's yours! If you need any help feel free to ask.

@aimanjaffer
Copy link

Hey @nicolo-ribaudo pardon my ignorance, I'm new to this codebase and I was wondering if there is any documentation for the internal methods such as this.eat() and this.expect(). Will greatly appreciate your assistance!

@fedeci
Copy link
Member

fedeci commented Sep 3, 2021

Nope, there are no docs available for internal parser methods, however you can ask on Slack and you will surely find someone that can help you.
For example eat(_token) checks if the specified token matches the current state, if it does the methods skips it returning true, if it doesn't the methods returns false. It is just a sugar for .matches(_token) and .next().

expect(_token) instead returns unexpected() error if the current state token does not match the provided one.

@aimanjaffer
Copy link

@fedeci Thank you so much for the explanation. Will definitely use the slack channel for these sorts of queries in the future!!

@nicolo-ribaudo
Copy link
Member

@aimanjaffer If you are asking because of this bug, please first leave some time (one more week) for @ChaitanyaGadodia since this bug is assigned to him 🙏

@aimanjaffer
Copy link

@nicolo-ribaudo Sure thing!!

@ozanhonamlioglu
Copy link
Contributor

@nicolo-ribaudo
If this bug is not maintained since September, can I take it? I want to solve it and it is gonna be my first issue.
Thanks

@macluiggy
Copy link

macluiggy commented Feb 23, 2022

I think the syntax is no correct, you should write this instead:

`type FuncWithDescription = {
  function: (...args: any[]) => any,
  string: string
}

const fnWithDescriptions: FuncWithDescription[] = [
  {
    function: (a,b,c) => a+b+c,
    string: 'Some string'
  }
]

@happycollision
Copy link
Author

happycollision commented Feb 23, 2022

@macluiggy
I am defining a tuple with named positional values, not a function that has an extra property. It’s valid syntax, but Babel gets confused.

@ozanhonamlioglu
I am not a team member, but I am willing to bet you can grab it. 🤷‍♂️

@ayush9398
Copy link

@nicolo-ribaudo I see there is a PR in draft state, is this issue still available?

@Harpica
Copy link
Contributor

Harpica commented Feb 14, 2023

Hello!
I tried to solve this issue (pr #15423 ), judging by the local test results (.\make test), everything seems to work locally, but some ci tests fail. Could somebody give me some guidence on this problem, please?

Harpica added a commit to Harpica/babel that referenced this issue Feb 24, 2023
@github-actions github-actions bot added the outdated A closed issue/PR that is archived due to age. Recommended to make a new issue label Jun 14, 2023
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jun 14, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: typescript good first issue i: bug outdated A closed issue/PR that is archived due to age. Recommended to make a new issue pkg: parser
Projects
None yet
10 participants