microsoft / microsoft/TypeScript

TS5097 is not reported for `require()` in checked JS or for clause-less side-effect imports

Aperta
#64,028 0 commenti 1 reazione 3 assegnatari Vedi su GitHub

@RyanCavanaugh ci sta già lavorando.

Dal 26/8/2026.

Bug
Lingua principale
Go
Stelle
111k
Fork
14.3k
Merge medio
2g 4h
PR unite (30g)
132

Descrizione

Regression from `typescript@6.0.2` to `typescript@7.0.2`. Also reproduces on `@typescript/native-preview@7.0.0-dev.20260707.2` and on current `main`. node v24.13.0, darwin/arm64.

## Steps to reproduce

Three files, no `tsconfig.json`:

`lib.ts`

```ts
export const value = 1;
```

`require.js`

```js
// @ts-check
const { value } = require('./lib.ts');
console.log(value);
```

`side-effect.ts`

```ts
import './lib.ts';
```

```sh
tsc --noEmit --allowJs require.js side-effect.ts
```

## Behavior with `typescript@6.0.2`

```
require.js(2,27): error TS5097: An import path can only end with a '.ts' extension when 'allowImportingTsExtensions' is enabled.
side-effect.ts(1,8): error TS5097: An import path can only end with a '.ts' extension when 'allowImportingTsExtensions' is enabled.
```

## Behavior with `typescript@7.0.2`

No output — both are silently accepted.

This is not a module-resolution difference: 7.0 resolves `require('./lib.ts')` and type-checks against it. Changing `console.log(value)` to `value(123)` yields the same TS2349 from both versions at the same position — only TS5097 is missing.

## Root cause

The two versions guard the diagnostic differently:

```
7.0 — tsc/internal/checker/checker.go:15334 if ast.FindAncestor(location, ast.IsEmittableImport) != nil {
6.0 — src/compiler/checker.ts:4779 if (errorNode && !(importOrExport?.isTypeOnly || findAncestor(location, isImportTypeNode))) {
```

7.0 asks *"will this import survive emit?"*; 6.0 asks *"is this explicitly type-only?"*. The answers differ for exactly two shapes: a CommonJS `require()`, which is a plain `CallExpression` that [`IsEmittableImport`](https://github.com/microsoft/TypeScript/blob/main/tsc/internal/ast/utilities.go#L3205) never matched, and a clause-less side-effect import, which stopped matching in [typescript-go#1198](https://github.com/microsoft/typescript-go/pull/1198) — a fix for [typescript-go#1190](https://github.com/microsoft/typescript-go/issues/1190) in the adjacent `.d.ts` branch, which shares the same predicate.

## Full matrix

| case | 6.0.2 | 7.0.2 |
| --- | --- | --- |
| `require('./lib.ts')` in checked JS | TS5097 | — |
| `import './lib.ts'` | TS5097 | — |
| `import { value } from './lib.ts'` | TS5097 | TS5097 |
| `import { value } from './lib.ts'` in JS | TS5097 | TS5097 |
| `export { value } from './lib.ts'` | TS5097 | TS5097 |
| `import('./lib.ts')` | TS5097 | TS5097 |
| `import lib = require('./lib.ts')` | TS5097 | TS5097 |
| `import type { Thing } from './lib.ts'` | — | — |
| `export type { Thing } from './lib.ts'` | — | — |
| `import('./lib.ts').Thing` in type position | — | — |
| `import './types.d.ts'` | — | — |

The versions disagree only on the first two rows; the last four are negative cases where both correctly stay silent.

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Valutazione

Questa issue non è ancora stata valutata.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.