TypeScript 4.5.4 separates JSX tag completion from attribute snippets
TypeScript 4.5.4 stops offering an attribute initializer while completing a tag name. The fix accounts for an unfinished JSX expression whose temporary parse can resemble an attribute position.
An editor has to offer completions before the source has become a valid finished program. That makes the parser's interpretation of an unfinished expression part of the editing experience. TypeScript 4.5.4 fixes a case where completing a JSX tag name could insert attribute-initializer syntax. The npm registry records its publication on December 13, and the release note identifies the correction.
The visible failure is specific. A user starts typing an element name, selects the suggested completion, and receives text shaped like an attribute assignment instead of just the intended tag name. The completion engine has selected a plausible name but applied the wrong edit form for the location.
I consider this part of the practical value TypeScript provides to web development. Completion should reduce the work needed to express an interface. When a suggestion inserts syntax belonging to another grammatical role, the user has to understand and undo the tool's interpretation before continuing.
Attribute snippets intentionally insert more than a name
The TypeScript 4.5 announcement describes JSX attribute snippet completions. A snippet can insert an initializer and place the cursor where its value belongs. The tool can use the attribute's type to choose an appropriate initializer, and editor preferences affect that behavior.
That is useful inside an element's attribute list. The completion represents a property assignment, so inserting the value position saves an additional editing step. At the beginning of the tag name, however, the same insertion creates syntax that does not describe the operation the user requested.
The December issue report gives a reproduction inside a React fragment. Typing an opening angle bracket and part of an element name, then accepting a suggestion, could produce button={}. The report identifies this as an editing failure, rather than a new restriction on which JSX tags the compiler accepts.
That distinction matters when verifying a language-service change. A finished file can parse and type-check correctly while a completion applied to an earlier unfinished state is wrong. Checking only final source validity does not exercise the path where the language service constructs the edit.
The unfinished parse can resemble an attribute
The 4.5.3 completion implementation decides whether to construct an attribute snippet using the symbol's displayed kind and the snippet-related preferences. If the symbol appears to be a JSX attribute and the relevant preferences permit snippets, the path can add an initializer.
The 4.5.4 implementation adds another location check. Its comment explains that text after an opening angle bracket can appear as an attribute while the tag remains unclosed. A symbol classification derived from that temporary parse is therefore insufficient to decide which edit the user needs.
The new condition examines whether the location is a less-than token and whether that token begins at the same position as its parent. The comment distinguishes this case from a binary expression. When the condition indicates a potentially incomplete tag name, the engine does not offer the JSX attribute snippet through that branch.
This is a narrow guard around snippet construction. It preserves the ordinary preference checks and the attribute-kind test. The patch does not disable attribute snippets everywhere or change every occurrence of the less-than character into a tag-name context.
A name and an edit have separate correctness requirements
The failure illustrates why a completion entry needs more context than its label. A candidate can have the right spelling while the associated insertion belongs to a different syntactic operation. Snippet text adds another layer because it can introduce punctuation and cursor positions beyond the name itself.
The patch checks the location before taking that extra step. This lets the engine avoid a misleading initializer while continuing to support snippets in actual attribute positions. The relevant requirement is that the generated edit correspond to the user's current grammatical task.
This also explains the importance of testing incomplete source in editor tooling. Missing delimiters are normal during typing, and a parser may recover by assigning provisional roles to nearby tokens. A language service has to use that recovered structure without assuming every role is the final interpretation the user intends.
I prefer this targeted correction because it preserves the useful attribute feature while accounting for the ambiguous state that triggered it incorrectly. The source comment records the unfinished JSX shape, which makes the reason for the position test available to future maintainers.
TypeScript 4.5.4 supplies the corrected completion behavior in the maintenance package. The release record and the issue describe the observed edit, while the tagged implementation explains the additional syntax check. A tag-name completion no longer acquires an attribute initializer merely because the unfinished parse temporarily makes that path appear applicable.