Description
TypeScript Version: 2.0.2
Code
Unfortunately, I have not been able to construct a reduced testcase, so I prepared a branch in the failing project to demonstrate the issue. Please checkout
https://github.com/DirtyHairy/6502.ts
and switch to the branch ts-broken
. Doing npm install
and grunt initial
will demonstrate the issue. After that, the failing compile can be retriggered via grunt ts
.
Expected behavior:
Project builds.
Actual behavior:
Using tsc v2.0.2
src/machine/stella/Board.ts(139,16): error TS2365: Operator '!==' cannot be applied to types 'ExecutionState.boot' and 'ExecutionState.fetch'
The code used to compile fine before 2.0.2 . The failing code fragment is this function:
boot(): Board {
let cycles = 0,
cpuCycles = 0;
this.reset();
if (this._cpu.executionState !== CpuInterface.ExecutionState.boot)
throw new Error("Already booted!");
while (this._cpu.executionState !== CpuInterface.ExecutionState.fetch) {
this._cycle();
cycles++;
if (this._subClock === 0) {
cpuCycles++;
}
}
this.cpuClock.dispatch(cpuCycles);
this.clock.dispatch(cycles);
return this;
}
The corresponding types are declared in this snippet:
interface CpuInterface {
// [...]
executionState: CpuInterface.ExecutionState;
// [...]
}
module CpuInterface {
export const enum ExecutionState {
boot, fetch, execute
}
// [...]
}
I think the problem was introduced when enum values were split into different types, and I suspect that two issues are at work here:
- The assertion leads the compiler to infer the type of
this._cpu.executionState
to beCpuInterface.ExecutionState.boot
. However, callingthis.cycle()
will mutate the execution state. - The compiler deems the two sides of
!==
to be of different type and rejects the comparision.
After introducing a manual cast
while (this._cpu.executionState as CpuInterface.ExecutionState !== CpuInterface.ExecutionState.fetch) {
the code compiles fine
However, as I said, I have not been able to construct a reduced test case, so some other aspect of my code seems to contribute to the compiler's confusion 😏