Repository navigation
Description
🔎 Search Terms
SymbolConstructor declaration emit, TS2693 d.ts, Symbol.iterator computed property d.ts, well-known symbol declaration emit
🕗 Version & Regression Information
Regression in 7.x.
- Fails: 7.0.1-rc, 7.0.2, 7.1.0-dev.20260708.3 (first 7.1 nightly), 7.1.0-beta, 7.1.0-dev.20261106.1
- Works: 5.9.3, 6.0.3
⏯ Playground Link
(Playground v2, 7.1.0-dev.20261108.1: Emit → src/index.d.ts shows [SymbolConstructor.iterator](). Same project on 6.0.3, correct [S.iterator](): https://www.typescriptlang.org/play/v2/?ts=6.0.3#code/v2/N4IghgxgLglgbgUwGIwDYJALhAegO4D2ATgNYDOADpAjmURDjAHYAmCAHgHRRkgA0IAGZoEvTKHzFyVCDR4QCTYQHNOAKzKKsIYAB0mAAgO6QCgLYURRAPIVYisicwG9ho8ZBQwRZQihOPUSYOf359dw8zAhYAV3QAkyCQkz5w9xMyKCIYaACsmIRUtyMTNghUbzB7JjyiArSAX30mpn5cQlJKalp6RlYObjFTBygDAGUDAF5xgE8zACMCVABufQ4KYlGFJkyDIjAmXymXAwAqAG0xucXUThgoBH2oYgBdAAoAShOZmARUFgMAEZlgYGqDVq0GgIyH8ENAYFpxCANmR7gimABhJYxMytTCAgQotGKAAyzAQADkcfNHlgCSAYeh4Yoxl4iFAsagcXj6Yy4dVWd4oGTglSFrT8VCQIgiKjEQAmBpAA)
💻 Code
// lib.ts
const S = Symbol;
export const range = { *[Symbol.iterator]() { yield 1; } };// use.ts
import { range } from "./out/lib.js";
for (const x of range) console.log(x);🙁 Actual behavior
tsc --declaration --emitDeclarationOnly --target esnext --outDir out lib.ts writes (7.0.2):
declare const S: SymbolConstructor;
export declare const range: {
[SymbolConstructor.iterator](): Generator<number, void, unknown>;
};
export {};7.1.0-beta and 7.1.0-dev.20261106.1 no longer emit declare const S but keep [SymbolConstructor.iterator].
tsc --noEmit --target esnext --module nodenext use.ts:
out/lib.d.ts(3,6): error TS2693: 'SymbolConstructor' only refers to a type, but is being used as a value here.
use.ts(2,17): error TS2488: Type '{ [x: number]: () => Generator<number, void, unknown>; }' must have a '[Symbol.iterator]()' method that returns an iterator.
With --skipLibCheck the TS2693 goes away but the TS2488 stays: consumers can no longer iterate range.
🙂 Expected behavior
A key that refers to a value. 5.9.3 and 6.0.3 emit [S.iterator](): Generator<number, void, unknown>;, and use.ts checks without errors. [Symbol.iterator] would be fine too.
Additional information about the issue
The emitter writes the interface name (SymbolConstructor) where it needs a value. Any value of type SymbolConstructor in scope triggers it (const S = Symbol, or a parameter s: SymbolConstructor). Only inferred object types are affected; a class with a [Symbol.iterator]() method is emitted correctly.
This was found with an AI-assisted differential testing tool; the repro and outputs above were re-run on the listed versions.
Activity
[-]Declaration emit writes `[SymbolConstructor.iterator]` when a `SymbolConstructor` value is in scope[/-][+]7.x declaration emit regressions: `[SymbolConstructor.iterator]` key, and `readonly` dropped under a `const` type parameter[/+][-]7.x declaration emit regressions: `[SymbolConstructor.iterator]` key, and `readonly` dropped under a `const` type parameter[/-][+]Declaration emit writes `[SymbolConstructor.iterator]` as a computed key when a `SymbolConstructor` value is in scope[/+]