microsoft / microsoft/TypeScript

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

未关闭
#64,028 0 条评论 1 个 reaction 已指派 3 人 已被 @RyanCavanaugh 认领 在 GitHub 查看
Bug
主要语言
Go
星标
111k
派生
14.3k
平均合并
2 天 4 小时
30 天内合并 PR
132

描述

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.

贡献指南

打开贡献指南

评估

这个 Issue 还没有评估数据。

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。