Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 25, 2025

  • Change source field type in TSImportType from TSType<'a> to StringLiteral<'a> in crates/oxc_ast/src/ast/ts.rs
  • Remove #[estree(via = TSImportTypeSource)] attribute from the field
  • Run just ast to regenerate all derived code
  • Update the parser in crates/oxc_parser/src/ts/types.rs to parse a StringLiteral directly and emit errors for non-string literals
  • Delete the dead code TSImportTypeSource serializer from crates/oxc_ast/src/serialize/ts.rs
  • Add ts_string_literal_expected diagnostic (TS1141)
  • Update semantic snapshot for import-type-with-type-params.snap
  • Add test case for invalid import type source
  • Verify all tests pass
  • Simplify error recovery - just report error and create dummy string literal (per review feedback)
  • Fix spurious "Expected ')'" error by skipping invalid tokens in error recovery
Original prompt

This section details on the original issue you should resolve

<issue_title>AST: Make source field of TSImportType a StringLiteral</issue_title>
<issue_description>Continuation of #16074.

The expression inside import(...) in TS context (TSImportType) cannot legally be anything other than a string literal.

Our parser is too liberal. We currently accept all kind of crazy stuff like:

type A = typeof import(`react`);
type B = typeof import(A);
type C = typeof import(`${A} ${B}`);
type D = typeof import(typeof import('react'));

Playground

TypeScript says these are all errors: TS Playground

AST change

We should alter the type of the source field from TSType<'a> to StringLiteral<'a>:

pub struct TSImportType<'a> {
pub span: Span,
#[estree(via = TSImportTypeSource)]
pub source: TSType<'a>,
pub options: Option<Box<'a, ObjectExpression<'a>>>,
pub qualifier: Option<TSImportTypeQualifier<'a>>,
pub type_arguments: Option<Box<'a, TSTypeParameterInstantiation<'a>>>,
}

pub struct TSImportType<'a> { 
    pub span: Span, 
-   #[estree(via = TSImportTypeSource)] 
-   pub source: TSType<'a>, 
+   pub source: StringLiteral<'a>, 
    pub options: Option<Box<'a, ObjectExpression<'a>>>, 
    pub qualifier: Option<TSImportTypeQualifier<'a>>, 
    pub type_arguments: Option<Box<'a, TSTypeParameterInstantiation<'a>>>, 
} 

Parser changes

If we change the AST first and run just ast to regenerate traits code, then all the places which rely on the type of source field will become apparent. We'll then need to alter the parser to throw an error if it encounters something that isn't a string literal.

ESTree serialization

Currently there's a custom deserializer to alter the AST on JS side from TSType to StringLiteral:

/// Serializer for `source` field of `TSImportType`.
///
/// * Field is named `argument` in Oxc AST.
/// * Serialized as a `StringLiteral` - all other values are illegal syntax.
#[ast_meta]
#[estree(
ts_type = "StringLiteral",
raw_deser = "
let source = DESER[TSType](POS_OFFSET.argument);
if (source.type === 'TSLiteralType') {
source = source.literal;
if (PARENT) source.parent = parent;
} else {
// Should be unreachable - illegal syntax
}
source
"
)]
pub struct TSImportTypeSource<'a, 'b>(pub &'b TSImportType<'a>);
impl ESTree for TSImportTypeSource<'_, '_> {
fn serialize<S: Serializer>(&self, serializer: S) {
let source = &self.0.argument;
if let TSType::TSLiteralType(ts_lit_type) = source
&& let TSLiteral::StringLiteral(str_lit) = &ts_lit_type.literal
{
str_lit.serialize(serializer);
return;
}
// Should be unreachable - illegal syntax
source.serialize(serializer);
}
}

Once we've changed the field type in AST, this code can be deleted - it's dead code once #[estree(via = TSImportTypeSource)] attribute is removed from the source field in AST struct.</issue_description>

Comments on the Issue (you are @copilot in this section)


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

@graphite-app
Copy link
Contributor

graphite-app bot commented Nov 25, 2025

How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:

  • 0-merge - adds this PR to the back of the merge queue
  • hotfix - for urgent hot fixes, skip the queue and merge this PR next

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

@camc314
Copy link
Contributor

camc314 commented Nov 25, 2025

@copilot update the PR title to have a conventional commit

Copilot AI changed the title [WIP] Make source field of TSImportType a StringLiteral feat(ast)!: Make source field of TSImportType a StringLiteral Nov 25, 2025
Copilot AI requested a review from camc314 November 25, 2025 16:00
Copy link
Contributor Author

Copilot AI commented Nov 25, 2025

@copilot update the PR title to have a conventional commit

The PR title is already using conventional commit format: feat(ast)!: Make 'source' field of 'TSImportType' a 'StringLiteral'. The ! after (ast) indicates this is a breaking change.

Copy link
Contributor

@camc314 camc314 left a comment

Choose a reason for hiding this comment

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

@copilot action the comment then run all of the coverage tests, including estree

@camc314 camc314 marked this pull request as ready for review November 25, 2025 17:31
Copilot AI review requested due to automatic review settings November 25, 2025 17:31
@camc314 camc314 requested a review from Dunqing as a code owner November 25, 2025 17:31
Copilot AI requested a review from camc314 November 25, 2025 17:31
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR refines the TypeScript AST by making the source field of TSImportType a StringLiteral instead of the overly permissive TSType. This enforces the TypeScript specification that requires import type sources to be string literals, rejecting invalid constructs like template literals, type references, or nested import types at parse time with the diagnostic TS1141.

Key Changes:

  • Changed AST field type from TSType<'a> to StringLiteral<'a> to match TypeScript's specification
  • Updated parser to validate and emit TS1141 errors for non-string literal import sources with fallback to empty string literal
  • Removed custom ESTree serialization code that was working around the previous overly permissive type

Reviewed changes

Copilot reviewed 6 out of 31 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
crates/oxc_ast/src/ast/ts.rs Changed source field type from TSType<'a> to StringLiteral<'a> and removed #[estree(via = TSImportTypeSource)] attribute
crates/oxc_parser/src/ts/types.rs Updated parser to check for string literals and emit TS1141 error for invalid sources with error recovery
crates/oxc_parser/src/diagnostics.rs Added ts_string_literal_expected diagnostic (TS1141)
crates/oxc_ast/src/serialize/ts.rs Removed dead TSImportTypeSource serializer code
crates/oxc_codegen/src/gen.rs Updated code generation to use print_string_literal instead of print for source field
tasks/coverage/misc/fail/import-type-source-not-string.ts Added test cases for invalid import type sources (template literals, type references, nested imports)
tasks/coverage/snapshots/*.snap Updated test snapshots showing improved negative test pass rates and correct TS1141 error reporting
crates/oxc_semantic/tests/fixtures/typescript-eslint/type-declaration/import-type-with-type-params.snap Updated semantic snapshot with corrected node ID due to AST structure change
crates/oxc_/src/generated/.rs Regenerated code from AST definitions with updated field types and memory offsets
napi/parser/generated/**/*.js Regenerated JavaScript bindings with updated deserializers and memory offsets
apps/oxlint/src-js/generated/deserialize.js Updated oxlint deserializer for new AST structure

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.

@camc314
Copy link
Contributor

camc314 commented Nov 25, 2025

@overlookmotel copiliot has done a decent job here. I've reviewed, and it looks good to me. This also fixes the codegen issue you mentioned. Hopefully its ok if I assign to you to review + merge 🙏

Copy link
Member

@overlookmotel overlookmotel left a comment

Choose a reason for hiding this comment

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

The error case logic in parser is a bit odd. But I can see that continuing parsing does provide a better diagnostic.

Thanks @camc314!

@overlookmotel overlookmotel added the 0-merge Merge with Graphite Merge Queue label Nov 25, 2025
Copy link
Member

overlookmotel commented Nov 25, 2025

Merge activity

@camc314
Copy link
Contributor

camc314 commented Nov 25, 2025

The error case logic in parser is a bit odd. But I can see that continuing parsing does provide a better diagnostic.

is it worth adding a comment explaining why it does it that way?

…16114)

- [x] Change `source` field type in `TSImportType` from `TSType<'a>` to `StringLiteral<'a>` in `crates/oxc_ast/src/ast/ts.rs`
- [x] Remove `#[estree(via = TSImportTypeSource)]` attribute from the field
- [x] Run `just ast` to regenerate all derived code
- [x] Update the parser in `crates/oxc_parser/src/ts/types.rs` to parse a `StringLiteral` directly and emit errors for non-string literals
- [x] Delete the dead code `TSImportTypeSource` serializer from `crates/oxc_ast/src/serialize/ts.rs`
- [x] Add `ts_string_literal_expected` diagnostic (TS1141)
- [x] Update semantic snapshot for `import-type-with-type-params.snap`
- [x] Add test case for invalid import type source
- [x] Verify all tests pass
- [x] Simplify error recovery - just report error and create dummy string literal (per review feedback)
- [x] Fix spurious "Expected ')'" error by skipping invalid tokens in error recovery

<!-- START COPILOT CODING AGENT SUFFIX -->

<details>

<summary>Original prompt</summary>

>
> ----
>
> *This section details on the original issue you should resolve*
>
> <issue_title>AST: Make `source` field of `TSImportType` a `StringLiteral`</issue_title>
> <issue_description>Continuation of #16074.
>
> The expression inside `import(...)` in TS context (`TSImportType`) cannot legally be anything other than a string literal.
>
> Our parser is too liberal. We currently accept all kind of crazy stuff like:
>
> ```ts
> type A = typeof import(`react`);
> type B = typeof import(A);
> type C = typeof import(`${A} ${B}`);
> type D = typeof import(typeof import('react'));
> ```
>
> [Playground](https://playground.oxc.rs/#eNptU9tOGzEQ/ZXIQqJIqUSRKqFUfQjQSJVooaUqL31g1jsbDF7bHc/molX+nfEmdkDhyfaZ+5njXmk1UbwOOJqOvo7SxTcj0wZP/OGBEDQ/nHz55waPiwOPabFdHkYf9dPN6Ki/2OwzXB14vX0dDxWPT1KAGiuvJr2izqXDGsdq0oCNOFaNpxaYkQrCBC4muCAmeguM9RVqCwRsvIvFuHw0jDGAxgK14OZ2/9S+DYRxHxK1D2Jm6tJj3Vbe5pdu5ju3zVgFoJga6xWuGF2UuoniKPOAtX75G7kjd9NxNDXOOqdTZzlTKom0wFsgCc3oEPf3/LtjMpJQF0NE6ZqN/kbkaYdKC4mroQW5v6KqV13EP1DtZ2Ko7k3Nj2pyNlbo6pvm2jgZUtlG2g1SjXf281OpZhJDvzrPe5qe4uruHfh/et2SD1JLQfzoEGusJafsyUh780vftpBs1goqc5gyrMyyzPOLfQnrxF1FoJ+R72RnEp6dMwotbjvf1ffVE2q+JwiSI5OaCg29TlmIrDrpEOlNGK4CkmnRMdgbuQJ7uvXRbFeUGFJCadHallQGmqNoU2E8O/30WaoIzVfYSOKZp0sLMc4M2rps7XUVUacfyuytreGC/kCGGliY2q32fVX3KspEQQSC5EB0mcWofY1zHD6QS0Iokn2KtZevv6PcOc9DroxYnGffIUv+C0lR+aPI5D5c4wJL0mfE8FNWkQU2hIpovZ2JgFPEAqnyMROe5nFpUclUbhuB64G+BJfbJuGJZoisNi/WFa5W)
>
> TypeScript says these are all errors: [TS Playground](https://www.typescriptlang.org/play/?#code/C4TwDgpgBAglC8VSQPYDMoEsC2YUCdgAKAA3wgEMBjYEgSgG4AoZaAIQSXAnS1wOIxGLblADCnVrxx5CpACQBvGAF8oStivrNWUACKTu0-nKkYZAogHJy1YFbrCgA)
>
> ### AST change
>
> We should alter the type of the `source` field from `TSType<'a>` to `StringLiteral<'a>`:
>
> https://github.com/oxc-project/oxc/blob/35d0ee491cbcd271ebceaac7e25cff0490ded5c4/crates/oxc_ast/src/ast/ts.rs#L1382-L1389
>
> ```diff
> pub struct TSImportType<'a> {
>     pub span: Span,
> -   #[estree(via = TSImportTypeSource)]
> -   pub source: TSType<'a>,
> +   pub source: StringLiteral<'a>,
>     pub options: Option<Box<'a, ObjectExpression<'a>>>,
>     pub qualifier: Option<TSImportTypeQualifier<'a>>,
>     pub type_arguments: Option<Box<'a, TSTypeParameterInstantiation<'a>>>,
> }
> ```
>
> ### Parser changes
>
> If we change the AST first and run `just ast` to regenerate traits code, then all the places which rely on the type of `source` field will become apparent. We'll then need to alter the parser to throw an error if it encounters something that isn't a string literal.
>
> ### `ESTree` serialization
>
> Currently there's a custom deserializer to alter the AST on JS side from `TSType` to `StringLiteral`:
>
> https://github.com/oxc-project/oxc/blob/91eb3f2be509cef11cffeff51fac61a3a4fbd12c/crates/oxc_ast/src/serialize/ts.rs#L506-L538
>
> Once we've changed the field type in AST, this code can be deleted - it's dead code once `#[estree(via = TSImportTypeSource)]` attribute is removed from the `source` field in AST struct.</issue_description>
>
> ## Comments on the Issue (you are @copilot in this section)
>
> <comments>
> </comments>
>

</details>

- Fixes #16111

<!-- START COPILOT CODING AGENT TIPS -->
---

💬 We'd love your input! Share your thoughts on Copilot coding agent in our [2 minute survey](https://gh.io/copilot-coding-agent-survey).
@overlookmotel
Copy link
Member

is it worth adding a comment explaining why it does it that way?

Yes I suppose that'd be ideal.

@graphite-app graphite-app bot merged commit 74cf572 into main Nov 25, 2025
21 checks passed
@graphite-app graphite-app bot deleted the copilot/make-source-field-string-literal branch November 25, 2025 18:57
@graphite-app graphite-app bot removed the 0-merge Merge with Graphite Merge Queue label Nov 25, 2025
overlookmotel added a commit that referenced this pull request Nov 25, 2025
…utput (#16120)

PR #16114 fixed TSImportType codegen to prevent backticks in minified
output (which produces invalid TypeScript). This adds regression tests
to ensure the fix persists.

## Changes

- Added 4 test cases covering TSImportType variants:
  - Basic import types with single/double quotes
  - Import types with qualifiers (`.SomeType`)
  - Import types with type arguments (`<string>`)
- Tests verify both normal and minified output via snapshots

## Example

Input:
```typescript
type T = typeof import('react');
```

Minified output (now tested):
```typescript
type T=typeof import("react");  // ✓ double quotes, not backticks
```

The minify snapshot ensures backticks are never used, preventing invalid
TS like `import(\`react\`)`.

<!-- START COPILOT CODING AGENT SUFFIX -->



<details>

<summary>Original prompt</summary>

> 
> ----
> 
> *This section details on the original issue you should resolve*
> 
> <issue_title>Codegen: Do not use backticks when printing argument of
`TSImportType`</issue_title>
> <issue_description>Input:
> 
> ```ts
> type T = typeof import('react');
> ```
> 
> Codegen output (with `minify: true`):
> 
> ```ts
> type T=typeof import(`react`);
> ```
> 
>
[Playground](https://playground.oxc.rs/#eNptU01rGzEQ/StGl7TgQhooBJceSlJDIW3SJjSXXma1s44SrUYdzcY2xv+9o/VKTiCn1b7RfLw3TztjzcLINuLsbvZllg/UzVwfieXdCSNYOXn/+W8wc0NmsTM8hPzxLohZdOATzk1H3IMIckWEIaQMV8Ql8iDYXqL1wCCOQqrB9YMTTBEsmoXwoEgPYeX1b7pgqY+M6ZiRLMV6OW37hnz5s91qurafmwic8lw7gxvBkLRtppuUDnhP698oA4frQZJrcTkEmwcrlXJL5Ge8AdbUgo55f86/B2GnBW0NJNSpxdlvzMQTqiNkqcYR9PxCqZ0ZEt5Bc+Qk0Ny7Vh7M4mxuMLTX3ZULStL4TseN2k2m+PmpdnNZoV8DyVGmx7S5fQP+l/9umKL2MpA+BMQWW62pa3I63uqC+h5yzHtFlYerZJXLuvDX+Bq2WbuGwT6h3OrKNL1cLij0eJh86k/NI1q5Z4hao4iaG42zfhUVshl0QuRXabiJyK7HIOCv9QhCfEPJHVaUFTIqabXaQVQBXqFa02A6O/34SbuozJfYaeEl8YWHlJYOfVu39rKLmpPGNsdo76SiP1CgBVGlptW+beqdScooqkGQA6gvixkttbjC8f2EbIRq2cfUkj7DSfIQSMZaBfG4KnfHKuUtZEeVh6LMKV7hM9aiT4jxp66iGGxMVdOSX6qBc8YzckOpCJ75hLyoHKqnvcLtKF+G62mf8Sxz4bT/D3SBh38=)
> 
> This is invalid TypeScript. TS appears to require the argument to be a
string literal, and nothing else - template literal is not allowable
here.
> 
> [TS
Playground](https://www.typescriptlang.org/play/?#code/C4TwDgpgBAglC8VSQPYDMoEsC2YUCdgAKAA3wgEMBjYEgSgG4AoIA)
> 
> Related to #16074.</issue_description>
> 
> <agent_instructions>The issue itself is solved. Add a test for
it.</agent_instructions>
> 
> ## Comments on the Issue (you are @copilot in this section)
> 
> <comments>
> <comment_new><author>@overlookmotel</author><body>
> We might want to do #16111 first. That'll make this fix
easier to implement.</body></comment_new>
> <comment_new><author>@overlookmotel</author><body>
> #16114 should have fixed this. We just need to add a
test to make sure.</body></comment_new>
> <comment_new><author>@camc314</author><body>
> There are tests for this, they regressed after just the AST change. I
fixed them back up in 16114 to avoid the regression</body></comment_new>
> </comments>
> 


</details>

- Fixes #16078

<!-- START COPILOT CODING AGENT TIPS -->
---

✨ Let Copilot coding agent [set things up for
you](https://github.com/oxc-project/oxc/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot)
— coding agent works faster and does higher quality work when set up for
your repo.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: overlookmotel <557937+overlookmotel@users.noreply.github.com>
leaysgur pushed a commit that referenced this pull request Nov 26, 2025
…16114)

- [x] Change `source` field type in `TSImportType` from `TSType<'a>` to `StringLiteral<'a>` in `crates/oxc_ast/src/ast/ts.rs`
- [x] Remove `#[estree(via = TSImportTypeSource)]` attribute from the field
- [x] Run `just ast` to regenerate all derived code
- [x] Update the parser in `crates/oxc_parser/src/ts/types.rs` to parse a `StringLiteral` directly and emit errors for non-string literals
- [x] Delete the dead code `TSImportTypeSource` serializer from `crates/oxc_ast/src/serialize/ts.rs`
- [x] Add `ts_string_literal_expected` diagnostic (TS1141)
- [x] Update semantic snapshot for `import-type-with-type-params.snap`
- [x] Add test case for invalid import type source
- [x] Verify all tests pass
- [x] Simplify error recovery - just report error and create dummy string literal (per review feedback)
- [x] Fix spurious "Expected ')'" error by skipping invalid tokens in error recovery

<!-- START COPILOT CODING AGENT SUFFIX -->

<details>

<summary>Original prompt</summary>

>
> ----
>
> *This section details on the original issue you should resolve*
>
> <issue_title>AST: Make `source` field of `TSImportType` a `StringLiteral`</issue_title>
> <issue_description>Continuation of #16074.
>
> The expression inside `import(...)` in TS context (`TSImportType`) cannot legally be anything other than a string literal.
>
> Our parser is too liberal. We currently accept all kind of crazy stuff like:
>
> ```ts
> type A = typeof import(`react`);
> type B = typeof import(A);
> type C = typeof import(`${A} ${B}`);
> type D = typeof import(typeof import('react'));
> ```
>
> [Playground](https://playground.oxc.rs/#eNptU9tOGzEQ/ZXIQqJIqUSRKqFUfQjQSJVooaUqL31g1jsbDF7bHc/molX+nfEmdkDhyfaZ+5njXmk1UbwOOJqOvo7SxTcj0wZP/OGBEDQ/nHz55waPiwOPabFdHkYf9dPN6Ki/2OwzXB14vX0dDxWPT1KAGiuvJr2izqXDGsdq0oCNOFaNpxaYkQrCBC4muCAmeguM9RVqCwRsvIvFuHw0jDGAxgK14OZ2/9S+DYRxHxK1D2Jm6tJj3Vbe5pdu5ju3zVgFoJga6xWuGF2UuoniKPOAtX75G7kjd9NxNDXOOqdTZzlTKom0wFsgCc3oEPf3/LtjMpJQF0NE6ZqN/kbkaYdKC4mroQW5v6KqV13EP1DtZ2Ko7k3Nj2pyNlbo6pvm2jgZUtlG2g1SjXf281OpZhJDvzrPe5qe4uruHfh/et2SD1JLQfzoEGusJafsyUh780vftpBs1goqc5gyrMyyzPOLfQnrxF1FoJ+R72RnEp6dMwotbjvf1ffVE2q+JwiSI5OaCg29TlmIrDrpEOlNGK4CkmnRMdgbuQJ7uvXRbFeUGFJCadHallQGmqNoU2E8O/30WaoIzVfYSOKZp0sLMc4M2rps7XUVUacfyuytreGC/kCGGliY2q32fVX3KspEQQSC5EB0mcWofY1zHD6QS0Iokn2KtZevv6PcOc9DroxYnGffIUv+C0lR+aPI5D5c4wJL0mfE8FNWkQU2hIpovZ2JgFPEAqnyMROe5nFpUclUbhuB64G+BJfbJuGJZoisNi/WFa5W)
>
> TypeScript says these are all errors: [TS Playground](https://www.typescriptlang.org/play/?#code/C4TwDgpgBAglC8VSQPYDMoEsC2YUCdgAKAA3wgEMBjYEgSgG4AoZaAIQSXAnS1wOIxGLblADCnVrxx5CpACQBvGAF8oStivrNWUACKTu0-nKkYZAogHJy1YFbrCgA)
>
> ### AST change
>
> We should alter the type of the `source` field from `TSType<'a>` to `StringLiteral<'a>`:
>
> https://github.com/oxc-project/oxc/blob/35d0ee491cbcd271ebceaac7e25cff0490ded5c4/crates/oxc_ast/src/ast/ts.rs#L1382-L1389
>
> ```diff
> pub struct TSImportType<'a> {
>     pub span: Span,
> -   #[estree(via = TSImportTypeSource)]
> -   pub source: TSType<'a>,
> +   pub source: StringLiteral<'a>,
>     pub options: Option<Box<'a, ObjectExpression<'a>>>,
>     pub qualifier: Option<TSImportTypeQualifier<'a>>,
>     pub type_arguments: Option<Box<'a, TSTypeParameterInstantiation<'a>>>,
> }
> ```
>
> ### Parser changes
>
> If we change the AST first and run `just ast` to regenerate traits code, then all the places which rely on the type of `source` field will become apparent. We'll then need to alter the parser to throw an error if it encounters something that isn't a string literal.
>
> ### `ESTree` serialization
>
> Currently there's a custom deserializer to alter the AST on JS side from `TSType` to `StringLiteral`:
>
> https://github.com/oxc-project/oxc/blob/91eb3f2be509cef11cffeff51fac61a3a4fbd12c/crates/oxc_ast/src/serialize/ts.rs#L506-L538
>
> Once we've changed the field type in AST, this code can be deleted - it's dead code once `#[estree(via = TSImportTypeSource)]` attribute is removed from the `source` field in AST struct.</issue_description>
>
> ## Comments on the Issue (you are @copilot in this section)
>
> <comments>
> </comments>
>

</details>

- Fixes #16111

<!-- START COPILOT CODING AGENT TIPS -->
---

💬 We'd love your input! Share your thoughts on Copilot coding agent in our [2 minute survey](https://gh.io/copilot-coding-agent-survey).
leaysgur pushed a commit that referenced this pull request Nov 26, 2025
…utput (#16120)

PR #16114 fixed TSImportType codegen to prevent backticks in minified
output (which produces invalid TypeScript). This adds regression tests
to ensure the fix persists.

## Changes

- Added 4 test cases covering TSImportType variants:
  - Basic import types with single/double quotes
  - Import types with qualifiers (`.SomeType`)
  - Import types with type arguments (`<string>`)
- Tests verify both normal and minified output via snapshots

## Example

Input:
```typescript
type T = typeof import('react');
```

Minified output (now tested):
```typescript
type T=typeof import("react");  // ✓ double quotes, not backticks
```

The minify snapshot ensures backticks are never used, preventing invalid
TS like `import(\`react\`)`.

<!-- START COPILOT CODING AGENT SUFFIX -->



<details>

<summary>Original prompt</summary>

> 
> ----
> 
> *This section details on the original issue you should resolve*
> 
> <issue_title>Codegen: Do not use backticks when printing argument of
`TSImportType`</issue_title>
> <issue_description>Input:
> 
> ```ts
> type T = typeof import('react');
> ```
> 
> Codegen output (with `minify: true`):
> 
> ```ts
> type T=typeof import(`react`);
> ```
> 
>
[Playground](https://playground.oxc.rs/#eNptU01rGzEQ/StGl7TgQhooBJceSlJDIW3SJjSXXma1s44SrUYdzcY2xv+9o/VKTiCn1b7RfLw3TztjzcLINuLsbvZllg/UzVwfieXdCSNYOXn/+W8wc0NmsTM8hPzxLohZdOATzk1H3IMIckWEIaQMV8Ql8iDYXqL1wCCOQqrB9YMTTBEsmoXwoEgPYeX1b7pgqY+M6ZiRLMV6OW37hnz5s91qurafmwic8lw7gxvBkLRtppuUDnhP698oA4frQZJrcTkEmwcrlXJL5Ge8AdbUgo55f86/B2GnBW0NJNSpxdlvzMQTqiNkqcYR9PxCqZ0ZEt5Bc+Qk0Ny7Vh7M4mxuMLTX3ZULStL4TseN2k2m+PmpdnNZoV8DyVGmx7S5fQP+l/9umKL2MpA+BMQWW62pa3I63uqC+h5yzHtFlYerZJXLuvDX+Bq2WbuGwT6h3OrKNL1cLij0eJh86k/NI1q5Z4hao4iaG42zfhUVshl0QuRXabiJyK7HIOCv9QhCfEPJHVaUFTIqabXaQVQBXqFa02A6O/34SbuozJfYaeEl8YWHlJYOfVu39rKLmpPGNsdo76SiP1CgBVGlptW+beqdScooqkGQA6gvixkttbjC8f2EbIRq2cfUkj7DSfIQSMZaBfG4KnfHKuUtZEeVh6LMKV7hM9aiT4jxp66iGGxMVdOSX6qBc8YzckOpCJ75hLyoHKqnvcLtKF+G62mf8Sxz4bT/D3SBh38=)
> 
> This is invalid TypeScript. TS appears to require the argument to be a
string literal, and nothing else - template literal is not allowable
here.
> 
> [TS
Playground](https://www.typescriptlang.org/play/?#code/C4TwDgpgBAglC8VSQPYDMoEsC2YUCdgAKAA3wgEMBjYEgSgG4AoIA)
> 
> Related to #16074.</issue_description>
> 
> <agent_instructions>The issue itself is solved. Add a test for
it.</agent_instructions>
> 
> ## Comments on the Issue (you are @copilot in this section)
> 
> <comments>
> <comment_new><author>@overlookmotel</author><body>
> We might want to do #16111 first. That'll make this fix
easier to implement.</body></comment_new>
> <comment_new><author>@overlookmotel</author><body>
> #16114 should have fixed this. We just need to add a
test to make sure.</body></comment_new>
> <comment_new><author>@camc314</author><body>
> There are tests for this, they regressed after just the AST change. I
fixed them back up in 16114 to avoid the regression</body></comment_new>
> </comments>
> 


</details>

- Fixes #16078

<!-- START COPILOT CODING AGENT TIPS -->
---

✨ Let Copilot coding agent [set things up for
you](https://github.com/oxc-project/oxc/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot)
— coding agent works faster and does higher quality work when set up for
your repo.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: overlookmotel <557937+overlookmotel@users.noreply.github.com>
overlookmotel pushed a commit that referenced this pull request Dec 1, 2025
### 💥 BREAKING CHANGES

- 74cf572 ast: [**BREAKING**] Make `source` field of `TSImportType` a
`StringLiteral` (#16114) (copilot-swe-agent)
- 43156ae ast: [**BREAKING**] Rename `TSImportType` `argument` field to
`source` (#16110) (overlookmotel)
- 934d873 napi: [**BREAKING**] Drop `armv7-unknown-linux-musleabihf`
support (#16105) (Boshen)

### 🚀 Features

- 669afe0 ast: Add `Expression::is_jsx` method (#16154) (Dunqing)
- 17a8caa parser: Add diagnostic for JSX identifiers with hyphens
(#16133) (camchenry)
- 0549ae5 parser: Add diagnostic for expected ident after optional chain
(#16132) (camchenry)
- db839ae parser: Improve diagnostic for unexpected optional
declarations (#16131) (camchenry)
- bab4bc8 napi/parser: Add type annotations to parse-raw-worker test
(#15998) (camc314)

### 🐛 Bug Fixes

- 35ed36c traverse: Fix panic when truncating non-ASCII variable names
(#16265) (peter)
- 9149a26 linter/plugins, napi/parser: Deep freeze visitor keys (#16293)
(overlookmotel)
- 6b54dab minifier: Incorrect non-null object condition simplification
with `&&` and `||` (#16161) (sapphi-red)
- 9cc20a1 minifier: Avoid merging side effectful expressions to next
assignment statement if the side effect may change the left hand side
reference (#16165) (sapphi-red)
- 91eb3f2 ast/estree: Convert `TSImportType` `argument` field to
`Literal` (#16109) (overlookmotel)
- 1199cee parser: Reject invalid modifiers on parameter properties with
binding patterns (#16083) (camc314)
- f376325 traverse: Remove `console.log` from build script (#16049)
(overlookmotel)

### ⚡ Performance

- 82d784f lexer: Reduce bounds checks in `Lexer::get_string` (#16317)
(overlookmotel)
- cc2f352 span: Add `#[inline]` to `Atom` methods (#16311)
(overlookmotel)
- ffca070 span: Add `#[repr(transparent)]` to `Atom` (#16310)
(overlookmotel)
- 02bdf90 linter/plugins, napi/parser: Reuse arrays in visitor keys
(#16294) (overlookmotel)

### 📚 Documentation

- 891e0b4 parser: Add note about falling back to parse TSType in
TSImportType (#16119) (camc314)

Co-authored-by: Boshen <1430279+Boshen@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-ast Area - AST A-cli Area - CLI A-codegen Area - Code Generation A-formatter Area - Formatter A-linter Area - Linter A-linter-plugins Area - Linter JS plugins A-parser Area - Parser A-semantic Area - Semantic C-enhancement Category - New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AST: Make source field of TSImportType a StringLiteral

3 participants