mirror of
https://github.com/oxc-project/oxc.git
synced 2026-09-14 19:36:11 +08:00
17e7cf3ce4
Port of [microsoft/typescript-go#4192](https://github.com/microsoft/typescript-go/pull/4192), which fixes [microsoft/TypeScript#63527](https://github.com/microsoft/TypeScript/issues/63527). ## Problem `as`/`satisfies` are supposed to be erasable without changing runtime semantics. But for an expression of the form `a ## b as T $$ c`, where `##` has *lower* precedence than `$$`, erasing the assertion silently changes the parse: ```ts const x = 1 + 1 as number * 2; ``` This parses as `((1 + 1) as number) * 2` (= `4`), but textually erasing `as number` yields `1 + 1 * 2` (= `3`). TypeScript now rejects such constructs as a syntax error, forcing explicit parentheses. ## Change In `parse_binary_expression_rest`, after parsing an `as`/`satisfies` type, stop parsing if the following operator binds tighter than the operator that produced the running left-hand operand. This leaves the higher-precedence operator dangling and surfaces as a parse error. A chained `a as T as U` keeps referring back to the original operator's precedence (the tracked precedence is intentionally not updated while consuming `as`/`satisfies`), so `1 + 1 as any as number * 2` is rejected too. ## Behavior | Expression | Result | | --- | --- | | `1 as number * 2` | ok | | `1 * 1 as number + 2` | ok (`+` does not bind tighter than `*`) | | `1 + 1 as number * 2` | **error** | | `1 + 1 as any as number * 2` | **error** | | `1 >> 1 as number + 2` | **error** | | `(1 + 1 as number) * 2` | ok | `satisfies` behaves identically to `as`. ## Tests Added `misc` coverage fixtures mirroring the upstream test matrix: `pass/ts-erasable-as-satisfies.ts` for the erasable cases and `fail/ts-unerasable-{as,as-chained,satisfies}.ts` for the rejected ones. Full conformance (test262 / babel / typescript) shows zero regressions. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
5 lines
201 B
TypeScript
5 lines
201 B
TypeScript
// https://github.com/microsoft/TypeScript/issues/63527
|
|
// Same rule as `as`: erasing `satisfies number` would let `*` re-associate, so this
|
|
// is a syntax error.
|
|
const x = 1 + 1 satisfies number * 2;
|