Three positions where a compound TS-cast operand prints bare and the output is invalid or reassociates (same family as the fixed #127 / #121, different host positions):
(w as any) = [1]; // AssignmentExpression.left = TSAsExpression
prints w as any = [1]; - rejected by tsc and by babel's TS parser ("Invalid left-hand side in as").
(Map as any)++; // UpdateExpression.argument = TSAsExpression
prints Map as any++; - does not parse; same for the prefix form. The UpdateExpression printer writes operator + argument with no precedence check at all.
((M.g as any)<any>)([1]); // TSInstantiationExpression.expression = TSAsExpression
prints (M.g as any<any>)([1]); - on reparse the instantiation binds to any.
Suggested fix: wrap AssignmentExpression.left, UpdateExpression.argument and TSInstantiationExpression.expression when the operand's precedence requires it (for the assignment target specifically: a bare cast is not a valid target in the real TS grammar even though its precedence would not demand parens).
Context: found by a parse -> print -> reparse structural gate over a ~8.5k-file TS/JS corpus while adopting esrap in core-js's build plugin, then re-verified in isolation. esrap 2.3.5; the ASTs below come from @typescript-eslint/typescript-estree 8.67 with loc/range enabled, so the repros are independent of our own (oxc-based) pipeline.
Three positions where a compound TS-cast operand prints bare and the output is invalid or reassociates (same family as the fixed #127 / #121, different host positions):
prints
w as any = [1];- rejected by tsc and by babel's TS parser ("Invalid left-hand side in as").prints
Map as any++;- does not parse; same for the prefix form. TheUpdateExpressionprinter writes operator + argument with no precedence check at all.prints
(M.g as any<any>)([1]);- on reparse the instantiation binds toany.Suggested fix: wrap
AssignmentExpression.left,UpdateExpression.argumentandTSInstantiationExpression.expressionwhen the operand's precedence requires it (for the assignment target specifically: a bare cast is not a valid target in the real TS grammar even though its precedence would not demand parens).Context: found by a parse -> print -> reparse structural gate over a ~8.5k-file TS/JS corpus while adopting esrap in core-js's build plugin, then re-verified in isolation. esrap 2.3.5; the ASTs below come from
@typescript-eslint/typescript-estree8.67 withloc/rangeenabled, so the repros are independent of our own (oxc-based) pipeline.