ondras / rot.js

ROguelike Toolkit in JavaScript. Cool dungeon-related stuff, interactive manual, documentation, tests!
https://ondras.github.io/rot.js/hp/
BSD 3-Clause "New" or "Revised" License
2.33k stars 254 forks source link

Fix implicit any type for Scheduler.next()/remove() #145

Open bbugh opened 5 years ago

bbugh commented 5 years ago

Addressed Issues

Scheduler<T> takes a type, but its internal representation of the object tracker (_current) was set to any instead of T. This resulted in next() returning any, which lost typing and required unnecessary casting when it is called.

This also creates an error that could be caught at compile time, as next() can also return null, which is not enforced by the type checker.

Lastly, remove(thing: any) lost the compiler-time checking when calling it.

Fixes

This fixes next() and remove() to use the expected T so that the type checker catches all of these issues with all of the schedulers.

I didn't run the make process with the PR because I'm unclear if you do that yourself, but I'm happy to push another commit with doc/lib built.

Example

From the documentation, here's an example of where this was going wrong:


interface SpeedyActor {
  number: number
  getSpeed: () => number
}

const scheduler = new Scheduler.Speed<SpeedyActor>()

/* simulate several turns */
const turns = []
for (let i = 0; i < 40; i++) {
    const current = scheduler.next() // without this PR, `current` is `any`
    // `current` can be null, but this isn't type check enforced
    turns.push(current.number) // `current` not type checked during usage either
}

scheduler.remove("bad entry") // should be a typeof SpeedyActor but it will take anything

These issues are fixed by the PR.