Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE] Test all supported TS versions in CI #20204

Merged
merged 3 commits into from
Sep 27, 2022
Merged

Conversation

chriskrycho
Copy link
Contributor

@chriskrycho chriskrycho commented Sep 21, 2022

As part of implementing RFC 0800, introduce support for testing all supported versions of TypeScript against our types. For the moment, the only additional supported version is the TypeScript nightly (next) build. When we get to publishing stable types, the current version will be the first version we support, and we will add new versions to the matrix over time in line with the "rolling window" support policy.

Additionally, remove type checking from the lint scripts and create a new set of type-check scripts instead. This is pragmatic, not philosophical: we treat it differently from the "lints" here in that we need to be able to run it repeatedly against different versions, whereas the lints are all one-and-done.


@chriskrycho
Copy link
Contributor Author

Heyoooo, adding tests for typescript@next already caught an issue! 🎉 I’ll get this fixed in a backwards-compatible way tomorrow and update.

@chriskrycho chriskrycho added the TypeScript Work on Ember’s types label Sep 22, 2022
@chriskrycho chriskrycho marked this pull request as ready for review September 26, 2022 21:55
@chriskrycho chriskrycho force-pushed the add-ts-semver-ci branch 2 times, most recently from f5a4a6b to 9e588a8 Compare September 27, 2022 02:56
// but some older consumers still use this basic shape.
interface GlimmerIterable<T> {
length: number;
forEach(fn: (value: T) => void): void;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aside: I spent some time mucking with .forEach() vs. Symbol.iterator on perf.link and in microbenchmarks, preferring .forEach() seems to be a good win in most scenarios:

  • .forEach() consistently wins by at least 65% in JSC
  • .forEach() always wins by at least a factor of 5 in SpiderMonkey
  • .forEach() is around 100% faster for small-ish arrays and never less than 20% slower for even very large arrays (I tested with up to 1 million items)

These are microbenchmarks, so they may be fairly misleading in real-world scenarios, but we should think about whether it might make sense to get some real-world data on that impact and if so consider whether/how to employ it in other places in the app. Here, I suggest we follow up on this PR by just using .forEach(): it lets us get rid of these TS shenanigans entirely, and for the places this is used I suspect that just using .forEach() will always be a win or close enough.

As part of implementing RFC 0800, introduce support for testing all
supported versions of TypeScript against our types. For the moment, the
only additional supported version is the TypeScript nightly (`next`)
build. When we get to publishing stable types, the current version will
be the first version we support, and we will add new versions to the
matrix over time in line with the "rolling window" support policy.

Additionally, *remove* type checking from the `lint` scripts and create
a new set of `type-check` scripts instead. This is pragmatic, not
philosophical: we treat it differently from the "lints" here in that we
need to be able to run it repeatedly against different versions,
whereas the lints are all one-and-done.
TS 4.9 understands the `in` operator and catches two issues for us which
earlier versions did not:

1. We were checking `name in model` in `Route#serialize` without
   checking that `model` there is an object. Given that a route's model
   is *not* guaranteed to be an object, this was a runtime error waiting
   to happen. `'a' in 2` will produce `TypeError: 2 is not an Object.'

2. We were checking for `Symbol.iterator in Array` in an internal
   `iterate()` utility in the `@ember/debug/data-adapter` package. This
   check is *always* true when targeting ES6 or newer for arrays, which
   would *appear* to makie the `else` branch a no-op on all supported
   browsers. Unfortunately, at least some consumers of this API
   implement a narrower contract for iterables (presumably due to
   legacy needs to interop with IE11 in Ember < 4.x). In those cases,
   we really have an iterable, *not* an array.
@chriskrycho chriskrycho merged commit 4b3af50 into master Sep 27, 2022
@chriskrycho chriskrycho deleted the add-ts-semver-ci branch September 27, 2022 16:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
TypeScript Work on Ember’s types
Projects
None yet
Development

Successfully merging this pull request may close these issues.

add type tests infrastructure for supported TS versions
2 participants