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

@swc/wasm-typescript handling () => <T>{} #9295

Closed
acutmore opened this issue Jul 19, 2024 · 3 comments · Fixed by #9328
Closed

@swc/wasm-typescript handling () => <T>{} #9295

acutmore opened this issue Jul 19, 2024 · 3 comments · Fixed by #9328
Assignees
Labels
Milestone

Comments

@acutmore
Copy link

acutmore commented Jul 19, 2024

Describe the bug

TypeScript's (legacy) prefix style type assertions (<Type>val instead of (val as Type)) cannot always be safely removed in "strip-only" mode when they are at the start of the body of an arrow function.

Input code

import * as swc from "@swc/wasm-typescript";

const input = `(() => <any>{})`;
const output = swc.transformSync(input, { mode: "strip-only" });

console.log(output.code);

Config

{ "mode": "strip-only" }

Playground link (or link to the minimal reproduction)

no playground support for wasm-typescript yet: swc-project/swc-playground#42

SWC Info output

No response

Expected behavior

Either error or (if possible) produce JS with matching semantics as the input i.e. the equivalent of: () => ({});

Actual behavior

Resulting code is: (() => {}) which has different semantics to the input.

Version

@swc/wasm-typescript@1.7.0

Additional context

I think it's not possible to solve this in all cases. So it might be best to error for arrow functions that start with <Type>{.

There are some cases that can work with "strip-only":

let f = () => <T>{};

can strip and keep the JS in place with:

let f = () => 0||{};

But that approach does not work for:

let f = () => <T>{p:null}.p ?? g();

which could not be changed to:

let f = () => 0||{p:null}.p ?? g();

As it is invalid to have || and ?? at the same level.

I would be very interesting if there was a way to solve this, otherwise I think the solution is to error.

@acutmore acutmore added the C-bug label Jul 19, 2024
@kdy1 kdy1 assigned kdy1 and unassigned kdy1 Jul 20, 2024
@kdy1
Copy link
Member

kdy1 commented Jul 20, 2024

TypeScript's (legacy) prefix style type assertions (val instead of (val as Type)) cannot always be safely removed in "strip-only" mode when they are at the start of the body of an arrow function.

That's why we don't touch it.

@acutmore
Copy link
Author

acutmore commented Jul 22, 2024

That's why we don't touch it.

Hi @kdy1, thanks for taking a look. In my testing it looks like "strip-types" does remove it.

(() => <any>{}) becomes (() => {}). The first returns {} at runtime, the second returns undefined.

For the case where the arrow function body only contains the type-assertion and object literal I think there is a safe transform to: (() => 0||{}), which keeps the original JS in the same position with the same semantics. However there are niche inputs which I think don't have safe position-preserving transforms such as: (() => <T>{p:null}.p??g), though I admit the chances of someone writing that is low.

@kdy1 kdy1 added this to the Planned milestone Jul 22, 2024
@kdy1 kdy1 self-assigned this Jul 22, 2024
@kdy1 kdy1 closed this as completed in 4d60f52 Jul 24, 2024
@kdy1 kdy1 modified the milestones: Planned, v1.7.1 Jul 24, 2024
@swc-bot
Copy link
Collaborator

swc-bot commented Aug 23, 2024

This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@swc-project swc-project locked as resolved and limited conversation to collaborators Aug 23, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Development

Successfully merging a pull request may close this issue.

3 participants