Problem
After the paired-accessor transfer in #938, an explicit generic new expression for a nested ambient class merged with a namespace can substitute the accessor's setter type with the namespace object instead of the explicit type argument. An explicitly typed instance (declare const box: Nested.Box<boolean>) follows the correct read/write types, so this is a separate constructor-instantiation path, not a reason to weaken the accessor route.
Reproduction
first.d.ts:
declare module 'pkg' {
export namespace Nested {
export class Box<T> {
constructor();
get value(): string;
set value(input: T | number);
}
}
}second.d.ts:
declare module 'pkg' {
export namespace Nested.Box { export const extra: 3; }
}
declare module 'other' {
export namespace Nested {
export class Box<T> {
constructor();
get value(): T;
set value(input: T | boolean);
}
}
}main.ts:
import { Nested } from 'pkg';
import { Nested as Other } from 'other';
const box = new Nested.Box<boolean>();
const read: string = box.value;
box.value = 42;
box.value = true;
box.value = "bad";
const wrong: number = box.value;
const extra: 3 = Nested.Box.extra;
const other = new Other.Box<number>();
other.value = true;
other.value = "bad";
const wrongOther: string = other.value;
void read; void wrong; void extra; void wrongOther;Pinned TypeScript 5.9.3 reports four TS2322 diagnostics: invalid box.value = "bad", the wrong box.value read, invalid other.value = "bad", and the wrong other.value read. Under Home's 3,840 MB guarded Program test, the same fixture reported six TS2322 diagnostics. It rejected the valid box.value = 42 and box.value = true, saying the target type was { readonly Box: { new <T>(): Box; ... readonly extra: 3 } }—the nested namespace value, not boolean | number. The failing consumer offsets were 142, 158, 176, 201, 322, and 349. The separate declare const box: Nested.Box<boolean> fixture matches the TypeScript diagnostic codes and locations.
Acceptance
- Preserve the exact class-generic binder and the explicit
booleanargument through nested ambient class/namespace constructor invocation; no syntheticanyor namespace-object substitution. - Match TypeScript 5.9.3 codes and locations for valid/invalid reads and writes, including another module with the same class name.
- Add same-file, split-file, and reverse-add-order Program and CLI regressions under the memory guard.
- Investigate the
other.valueread after writes separately if it remains wider than TypeScript after the constructor path is corrected; do not count matching error totals alone as parity.