TypeScript 2.8.3 preserves used import aliases and required helpers
TypeScript 2.8.3 includes corrections to import organization and interoperability helper discovery. Both depend on preserving the meaning of an import while compiler tooling processes the surrounding file.
Renaming an imported value creates two names with different jobs. One selects the module's export, and the other identifies the binding used inside the importing file. An import organizer that checks the wrong name can remove a value the program still uses. TypeScript 2.8.3 includes a correction to that distinction.
The npm registry dates publication of 2.8.3 to April 19. The changes between the 2.8.1 and 2.8.3 tags include both the import-organizer fix and a separate correction to discovering interoperability helpers. These are maintenance changes to existing tooling, with regression examples explaining the affected behaviour.
I appreciate TypeScript most when its tools make careful web development easier without changing the program's meaning. Removing unused imports should be a routine editing operation. That convenience depends on the service knowing which local bindings the remaining code actually references.
An alias must be checked by its local name
The organizer patch changes the named-import filter to call isDeclarationUsed() with the import element's local name. The earlier code preferred propertyName, when present, over name. For a renamed import, those fields describe the exported name and the locally bound alias respectively.
The regression test imports two functions under new names and calls only one. Its expected organized output retains the used alias while removing the unused one. An equivalent illustrative case has a library exporting open and close, with the importing file renaming them.
import { open as begin, close as finish } from "lib";
begin();
After organization, the retained import must still bind begin to the module's open export. The unused finish binding can disappear. Testing whether the importing file refers to a local identifier named open asks the wrong question, since the call in that file uses begin.
This is a small implementation change with an observable editing consequence. The import element already contains the required information. The correction selects the identifier whose references determine local usage, so a source transformation does not mistake renaming for non-use.
The test also explains why sorting imports is only one part of the organizer's responsibility. Removing an element requires a semantic judgement about references. A text-based reordering operation can ignore that relationship, but deleting a binding cannot. The language service needs to preserve the connection among the imported export, local alias and call site.
Helper requirements accumulate across imports
Another included patch repairs a boolean used while examining external imports. The compiler records whether any import needs an import-star or import-default helper. Previously, processing a later import could overwrite that state with its own requirements. An ordinary import needing neither helper could consequently erase the fact that an earlier import did need one.
The correction combines the previous flag with the current import's helper requirements using logical OR. Once the file has established that a helper is necessary, an unrelated later import cannot remove that requirement. This is an aggregate property of the file, so accumulation is the appropriate operation.
The regression example enables esModuleInterop and helper imports, targeting CommonJS output. It has a default import followed by a named import, then uses both. The JavaScript baseline includes a tslib import and obtains the default-imported value through __importDefault. The later named import remains an ordinary module access.
This example identifies the specific interaction. The compiler knows how each individual import should transform. The bug lies in gathering the file-wide requirement that supports those transformations. Correct local transformations still need correct supporting declarations in the emitted file.
The helper test supplies declarations for the relevant tslib exports inside its fixture. That keeps the expected output focused on whether the compiler introduces and uses the helper import. A separate utility module re-exports its named function through another module, so the fixture also exercises that ordinary module path. The two import forms coexist in one consumer, which is necessary to expose the overwritten file-level flag.
Tooling correctness includes the generated program
The TypeScript 2.7 interoperability announcement explains why the helpers exist. CommonJS exports and ECMAScript default imports have different conventions, and esModuleInterop supplies an explicit emitted-code policy for connecting them. Its effect is therefore broader than accepting an import spelling in the checker.
A maintenance correction to helper discovery belongs to that runtime contract. The generated program must contain the machinery its import transformations call. An import list that type-checks successfully does not itself establish that every required helper has been emitted or imported correctly.
My judgement is that both fixes concern information the tools already possess but must preserve through processing. The organizer needs the local binding's usage, while the emitter needs the union of helper requirements across the file. Their regression examples make those obligations concrete, allowing a maintenance release to be assessed through the source edits and generated output it is supposed to preserve.