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

Astro transform fails on several forms of multiline exports #554

Open
1 task
duanwilliam opened this issue Sep 4, 2022 · 9 comments
Open
1 task

Astro transform fails on several forms of multiline exports #554

duanwilliam opened this issue Sep 4, 2022 · 9 comments
Labels
- P4: important Violate documented behavior or significantly improves performance (priority)

Comments

@duanwilliam
Copy link

duanwilliam commented Sep 4, 2022

What version of astro are you using?

1.1.5

Are you using an SSR adapter? If so, which one?

None

What package manager are you using?

pnpm

What operating system are you using?

WSL2

Describe the Bug

(don't know if this should go in the compiler repo)

(Seems similar to the recently submitted #536, but found independently and (I think) more accurate on reproduction / diagnosing the cause.)

Astro fails at parsing certain forms of multiline exports (not sure exactly why), some of which are not uncommon patterns.

For context, I encountered this bug when trying to define a Props interface for a component, that extended a subset of some other defined type:

export interface Props extends Pick<
    OtherType,
        | 'key1'
        | 'etc'
> {
    // ...
}

where I would consistently get an error message of

Transform failed with 1 error: [path/lineno/position]: ERROR: Expected ">" but found "$$[filename excluding extension]"

This error occurs not just for interfaces or generic types, but also for basic and union types if not on the same line as the export keyword (with slightly different expected/found in the error message):

export type Foo =
    'string'
export type UnionType =
    | 'foo'
    | 'bar'

It's not restricted to types, either:

export const foo =
    'foo'
export const noop =
    () => {}

Notably, these issues only occur relating to some part of the expression going to a new line, and only when the expression in question is being exported: if the export keyword is removed, the transform no longer fails. This can be seen in the minimal reproduction example.

Link to Minimal Reproducible Example

https://stackblitz.com/edit/github-hmtihg-ej7ccx?file=src/pages/index.astro

Participation

  • I am willing to submit a pull request for this issue.
@matthewp matthewp added the - P3: minor bug An edge case that only affects very specific usage (priority) label Sep 6, 2022
@matthewp matthewp self-assigned this Sep 23, 2022
@matthewp matthewp added - P2: has workaround Bug, but has workaround (priority) and removed - P3: minor bug An edge case that only affects very specific usage (priority) labels Sep 30, 2022
@matthewp matthewp removed their assignment Sep 30, 2022
@FredKSchott FredKSchott transferred this issue from withastro/astro Oct 7, 2022
@delucis
Copy link
Member

delucis commented Nov 28, 2022

Additional case reported on StackOverflow, which provides a CodeSandbox reproduction.

Works

---
import { SomeType } from 'package';

export type Props = SomeType & {
  margin?: number | string
};
---

Doesn’t work

---
import { SomeType } from 'package';

export type Props = {
  margin?: number | string
} & SomeType;
---

Throws an error:

Transform failed with 1 error: ERROR: Unexpected "&"

@TymekDev
Copy link

I see this issue marked as p2-has-workaround. What is this workaround? I looked for making Astro LSP ignore one particular line, but haven't found anything of use. Is there a way other than turning off LSP before write?

@Princesseuh
Copy link
Member

Princesseuh commented Jun 29, 2023

Just a note to anyone visiting this issue that exporting Props is not needed (and never has been) unless you're actually using it in other files.

I'll bump the prio back to a p3 because people hit it often and formatting can trigger this automatically

@Princesseuh Princesseuh added - P3: minor bug An edge case that only affects very specific usage (priority) and removed - P2: has workaround Bug, but has workaround (priority) labels Jun 29, 2023
@Princesseuh Princesseuh added - P4: important Violate documented behavior or significantly improves performance (priority) and removed - P3: minor bug An edge case that only affects very specific usage (priority) labels Aug 8, 2023
@yanickrochon
Copy link

yanickrochon commented Sep 30, 2023

Prettier formats code with this syntax, and it works fine in Next.js (haven't tried in other projects), so why is this failing, here?

Are unions like

type Foo =
 | string
 | number;

still valid TS (the documentation page no longer show this format).

@Princesseuh
Copy link
Member

Prettier formats code with this syntax, and it works fine in Next.js (haven't tried in other projects), so why is this failing, here?

Are unions like

type Foo =
 | string
 | number;

still valid TS (the documentation page no longer show this format).

Yes, this is valid TS. It's a bug in our compiler, only affects exported things though

@xavdid
Copy link

xavdid commented Oct 12, 2023

I was able to work around this by defining the type separately from the function:

type StaticPathResult = () => Promise<
  { params: { year: number }; props: Props }[]
>;

export const getStaticPaths: StaticPathResult = async () => {
  // ...
}

@fratzinger
Copy link

In my case it was prettier auto formatting forcing me into this issue.

My current workaround is to transform this:

type Test =
  | 'this'
  | 'test':

to this:

// prettier-ignore
type Test = 'this' | 'test'

@gersomvg
Copy link

Just hit this issue for the first time. I can confirm that altering the line breaks somewhat combined with a // prettier-ignore solves the issue.

@joediton
Copy link

I've hit this issue. Removing export resolves this issue

export type TBlock =
  | TBlock_Text
  | TBlock_CardsList
  | TBlock_CtaSection
  | TBlock_Iframe
  | TBlock_Hero;

My work arround

type TBlock_Union =
  | TBlock_Text
  | TBlock_CardsList
  | TBlock_CtaSection
  | TBlock_Iframe
  | TBlock_Hero;

export TBlock = TBlock_Union

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
- P4: important Violate documented behavior or significantly improves performance (priority)
Projects
None yet
Development

No branches or pull requests

10 participants