maildev@lists.thunderbird.net

Thunderbird email developers

View all threads

Using TypeScript to type check vanilla JS

PM
Paul Morris
Wed, Mar 20, 2019 12:44 PM

While looking into TypeScript again, I learned that you can use
TypeScript tooling to type check plain vanilla JS, which provides the
main benefits of TypeScript without having to introduce a compilation step:

https://www.typescriptlang.org/docs/handbook/type-checking-javascript-files.html

http://seg.phault.net/blog/2017/10/typescript-without-transpiling/

Basically, the TypeScript tooling uses type inference and type
annotations written as JSDoc comments to do a static analysis and catch
problems early.  Editors like VS Code can then catch problems
immediately as you edit code.

It's easy to gradually introduce the type checking on a file-by-file
basis.  It works alongside ESLint, and would be similar to what we're
already doing with linting, but going a step further.  Introducing it
would be low risk and easy to revert if it didn't work out well for some
reason.

The more I think about this the more I like it.  If we're going to be
writing JSDoc comments in any case, we might as well maximize the
benefits and get some static type checking out of it.  (And some help
keeping the comments accurate and up to date.)  Imagine how many tests
we would need to write to provide the same level of coverage for
catching these kinds of bugs at compile time.

Thoughts?

-Paul

While looking into TypeScript again, I learned that you can use TypeScript tooling to type check plain vanilla JS, which provides the main benefits of TypeScript without having to introduce a compilation step: https://www.typescriptlang.org/docs/handbook/type-checking-javascript-files.html http://seg.phault.net/blog/2017/10/typescript-without-transpiling/ Basically, the TypeScript tooling uses type inference and type annotations written as JSDoc comments to do a static analysis and catch problems early.  Editors like VS Code can then catch problems immediately as you edit code. It's easy to gradually introduce the type checking on a file-by-file basis.  It works alongside ESLint, and would be similar to what we're already doing with linting, but going a step further.  Introducing it would be low risk and easy to revert if it didn't work out well for some reason. The more I think about this the more I like it.  If we're going to be writing JSDoc comments in any case, we might as well maximize the benefits and get some static type checking out of it.  (And some help keeping the comments accurate and up to date.)  Imagine how many tests we would need to write to provide the same level of coverage for catching these kinds of bugs at compile time. Thoughts? -Paul
PL
Philippe Lieser
Wed, Mar 20, 2019 7:19 PM

I'm to some extent successfully using it in VS code for my Thunderbird
add-on. Already helped in finding a few bugs. There are however a few
limitations, which I believe will also affect the JS code in Thunderbird.

The biggest problem are Mozilla's JavaScript code modules, especially
that the .jsm extension is not supported.

Checking files which are using the .jsm extension instead of .js does
not work at all. See also
https://github.com/Microsoft/TypeScript/issues/15416

If I rename the modules to .js, it mostly works fine. The biggest
remaining problem is that I did not found a way to let the TS checker
know that each modules has it's own global name space.
E.g. the following is causing problems if in more than one module.
Without the comment to ignore errors, I get "Cannot redeclare
block-scoped variable 'Cu'.ts(2451)"

// @ts-ignore
const Cu = Components.utils;

I encountered a few other smaller issues, like that not all of JSDOC is
supported (e.g. @extends for non class types).
Adding a .d.ts file in addition (or as replacement) for the JSDOC often
helps.

On 20.03.2019 13:44, Paul Morris wrote:

While looking into TypeScript again, I learned that you can use
TypeScript tooling to type check plain vanilla JS, which provides the
main benefits of TypeScript without having to introduce a compilation step:

https://www.typescriptlang.org/docs/handbook/type-checking-javascript-files.html

http://seg.phault.net/blog/2017/10/typescript-without-transpiling/

Basically, the TypeScript tooling uses type inference and type
annotations written as JSDoc comments to do a static analysis and catch
problems early.  Editors like VS Code can then catch problems
immediately as you edit code.

It's easy to gradually introduce the type checking on a file-by-file
basis.  It works alongside ESLint, and would be similar to what we're
already doing with linting, but going a step further.  Introducing it
would be low risk and easy to revert if it didn't work out well for some
reason.

The more I think about this the more I like it.  If we're going to be
writing JSDoc comments in any case, we might as well maximize the
benefits and get some static type checking out of it.  (And some help
keeping the comments accurate and up to date.)  Imagine how many tests
we would need to write to provide the same level of coverage for
catching these kinds of bugs at compile time.

Thoughts?

-Paul


Maildev mailing list
Maildev@lists.thunderbird.net
http://lists.thunderbird.net/mailman/listinfo/maildev_lists.thunderbird.net

I'm to some extent successfully using it in VS code for my Thunderbird add-on. Already helped in finding a few bugs. There are however a few limitations, which I believe will also affect the JS code in Thunderbird. The biggest problem are Mozilla's JavaScript code modules, especially that the .jsm extension is not supported. Checking files which are using the .jsm extension instead of .js does not work at all. See also https://github.com/Microsoft/TypeScript/issues/15416 If I rename the modules to .js, it mostly works fine. The biggest remaining problem is that I did not found a way to let the TS checker know that each modules has it's own global name space. E.g. the following is causing problems if in more than one module. Without the comment to ignore errors, I get "Cannot redeclare block-scoped variable 'Cu'.ts(2451)" > // @ts-ignore > const Cu = Components.utils; I encountered a few other smaller issues, like that not all of JSDOC is supported (e.g. @extends for non class types). Adding a .d.ts file in addition (or as replacement) for the JSDOC often helps. On 20.03.2019 13:44, Paul Morris wrote: > While looking into TypeScript again, I learned that you can use > TypeScript tooling to type check plain vanilla JS, which provides the > main benefits of TypeScript without having to introduce a compilation step: > > https://www.typescriptlang.org/docs/handbook/type-checking-javascript-files.html > > > http://seg.phault.net/blog/2017/10/typescript-without-transpiling/ > > Basically, the TypeScript tooling uses type inference and type > annotations written as JSDoc comments to do a static analysis and catch > problems early.  Editors like VS Code can then catch problems > immediately as you edit code. > > It's easy to gradually introduce the type checking on a file-by-file > basis.  It works alongside ESLint, and would be similar to what we're > already doing with linting, but going a step further.  Introducing it > would be low risk and easy to revert if it didn't work out well for some > reason. > > The more I think about this the more I like it.  If we're going to be > writing JSDoc comments in any case, we might as well maximize the > benefits and get some static type checking out of it.  (And some help > keeping the comments accurate and up to date.)  Imagine how many tests > we would need to write to provide the same level of coverage for > catching these kinds of bugs at compile time. > > Thoughts? > > -Paul > > _______________________________________________ > Maildev mailing list > Maildev@lists.thunderbird.net > http://lists.thunderbird.net/mailman/listinfo/maildev_lists.thunderbird.net
MM
Magnus Melin
Thu, Mar 21, 2019 9:15 AM

Sound quite interesting! I'd be curious to know if there are any plans
to integrate @ts-check in mozilla-central

 -Magnus

On 20-03-2019 14:44, Paul Morris wrote:

While looking into TypeScript again, I learned that you can use
TypeScript tooling to type check plain vanilla JS, which provides the
main benefits of TypeScript without having to introduce a compilation
step:

https://www.typescriptlang.org/docs/handbook/type-checking-javascript-files.html

http://seg.phault.net/blog/2017/10/typescript-without-transpiling/

Basically, the TypeScript tooling uses type inference and type
annotations written as JSDoc comments to do a static analysis and
catch problems early.  Editors like VS Code can then catch problems
immediately as you edit code.

It's easy to gradually introduce the type checking on a file-by-file
basis.  It works alongside ESLint, and would be similar to what we're
already doing with linting, but going a step further.  Introducing it
would be low risk and easy to revert if it didn't work out well for
some reason.

The more I think about this the more I like it.  If we're going to be
writing JSDoc comments in any case, we might as well maximize the
benefits and get some static type checking out of it.  (And some help
keeping the comments accurate and up to date.)  Imagine how many tests
we would need to write to provide the same level of coverage for
catching these kinds of bugs at compile time.

Thoughts?

-Paul


Maildev mailing list
Maildev@lists.thunderbird.net
http://lists.thunderbird.net/mailman/listinfo/maildev_lists.thunderbird.net

Sound quite interesting! I'd be curious to know if there are any plans to integrate @ts-check in mozilla-central  -Magnus On 20-03-2019 14:44, Paul Morris wrote: > While looking into TypeScript again, I learned that you can use > TypeScript tooling to type check plain vanilla JS, which provides the > main benefits of TypeScript without having to introduce a compilation > step: > > https://www.typescriptlang.org/docs/handbook/type-checking-javascript-files.html > > > http://seg.phault.net/blog/2017/10/typescript-without-transpiling/ > > Basically, the TypeScript tooling uses type inference and type > annotations written as JSDoc comments to do a static analysis and > catch problems early.  Editors like VS Code can then catch problems > immediately as you edit code. > > It's easy to gradually introduce the type checking on a file-by-file > basis.  It works alongside ESLint, and would be similar to what we're > already doing with linting, but going a step further.  Introducing it > would be low risk and easy to revert if it didn't work out well for > some reason. > > The more I think about this the more I like it.  If we're going to be > writing JSDoc comments in any case, we might as well maximize the > benefits and get some static type checking out of it.  (And some help > keeping the comments accurate and up to date.)  Imagine how many tests > we would need to write to provide the same level of coverage for > catching these kinds of bugs at compile time. > > Thoughts? > > -Paul > > _______________________________________________ > Maildev mailing list > Maildev@lists.thunderbird.net > http://lists.thunderbird.net/mailman/listinfo/maildev_lists.thunderbird.net >
MB
Mark Banner
Thu, Mar 21, 2019 9:50 AM

We've looked at various options in the past, and none of them have
really fitted what we need. In the past, TypeScript also didn't support
JSDoc style comments at the time which didn't help (you had to do them
inline in function arguments etc).

Dave also did some investigations in this area, and he can probably give
a summary better than myself.

At the moment, I'm more looking to finish enabling ESLint everywhere,
and then getting a more consistent ruleset and enabling more rules.
We're also looking into set formatting of Javascript, in a similar way
to the clang-format effort that has been going on.

On 20-03-2019 14:44, Paul Morris wrote:

The more I think about this the more I like it.  If we're going to be
writing JSDoc comments in any case, we might as well maximize the
benefits and get some static type checking out of it.  (And some help
keeping the comments accurate and up to date.)  Imagine how many
tests we would need to write to provide the same level of coverage
for catching these kinds of bugs at compile time.

Are you suggesting this as an alternative to back-filling tests? Or just
in addition? Generally we should be adding tests for missing coverage of
functionality, static type checking won't get you everything. For
Firefox the general policy is to make sure changes to code are covered
by tests (so that we might eventually get good coverage everywhere).

Mark

We've looked at various options in the past, and none of them have really fitted what we need. In the past, TypeScript also didn't support JSDoc style comments at the time which didn't help (you had to do them inline in function arguments etc). Dave also did some investigations in this area, and he can probably give a summary better than myself. At the moment, I'm more looking to finish enabling ESLint everywhere, and then getting a more consistent ruleset and enabling more rules. We're also looking into set formatting of Javascript, in a similar way to the clang-format effort that has been going on. > On 20-03-2019 14:44, Paul Morris wrote: >> The more I think about this the more I like it.  If we're going to be >> writing JSDoc comments in any case, we might as well maximize the >> benefits and get some static type checking out of it.  (And some help >> keeping the comments accurate and up to date.)  Imagine how many >> tests we would need to write to provide the same level of coverage >> for catching these kinds of bugs at compile time. Are you suggesting this as an alternative to back-filling tests? Or just in addition? Generally we should be adding tests for missing coverage of functionality, static type checking won't get you everything. For Firefox the general policy is to make sure changes to code are covered by tests (so that we might eventually get good coverage everywhere). Mark
PM
Paul Morris
Thu, Mar 21, 2019 1:49 PM

On 3/21/19 5:50 AM, Mark Banner wrote:

Are you suggesting this as an alternative to back-filling tests? Or
just in addition?

Oh, definitely in addition to good test coverage.  (Just that one
wouldn't need to, say, write tests to check the types of values returned
from functions since that is covered by type checking. Those kinds of
bugs would show up immediately while editing.)

Generally we should be adding tests for missing coverage of
functionality, static type checking won't get you everything.

Yep, agreed.

I gave it a quick try by adding "// @ts-check" to the top of a JS file
in VS Code.  It seems to work well at first glance.  One issue though is
it assumes an HTML document not XUL.  For example:

  let listbox = document.getElementById("agenda-listbox");
  let item = listbox.selectedItem;

It complains: "Property 'selectedItem' does not exist on type
'HTMLElement'".

Maybe there's a way around that, but it might be a tricky one to solve.

-Paul

On 3/21/19 5:50 AM, Mark Banner wrote: > Are you suggesting this as an alternative to back-filling tests? Or > just in addition? Oh, definitely in addition to good test coverage.  (Just that one wouldn't need to, say, write tests to check the types of values returned from functions since that is covered by type checking. Those kinds of bugs would show up immediately while editing.) > Generally we should be adding tests for missing coverage of > functionality, static type checking won't get you everything. Yep, agreed. I gave it a quick try by adding "// @ts-check" to the top of a JS file in VS Code.  It seems to work well at first glance.  One issue though is it assumes an HTML document not XUL.  For example:   let listbox = document.getElementById("agenda-listbox");   let item = listbox.selectedItem; It complains: "Property 'selectedItem' does not exist on type 'HTMLElement'". Maybe there's a way around that, but it might be a tricky one to solve. -Paul
DT
Dave Townsend
Thu, Mar 21, 2019 3:21 PM

Yes, yet another project that I really want to dig into but is on the
back-burner behind other stuff that is more important right now. One of the
things I'm hoping will happen which will make this even more valuable is a
switch to using ES6 modules rather than our in-house JSMs which Typescript
doesn't understand at all. Anyway, right now I don't really have a good
summary of where this is at, just that it's something I'd love to have more
time to work on.

On Thu, Mar 21, 2019 at 2:50 AM Mark Banner mbanner@mozilla.com wrote:

We've looked at various options in the past, and none of them have
really fitted what we need. In the past, TypeScript also didn't support
JSDoc style comments at the time which didn't help (you had to do them
inline in function arguments etc).

Dave also did some investigations in this area, and he can probably give
a summary better than myself.

At the moment, I'm more looking to finish enabling ESLint everywhere,
and then getting a more consistent ruleset and enabling more rules.
We're also looking into set formatting of Javascript, in a similar way
to the clang-format effort that has been going on.

On 20-03-2019 14:44, Paul Morris wrote:

The more I think about this the more I like it.  If we're going to be
writing JSDoc comments in any case, we might as well maximize the
benefits and get some static type checking out of it.  (And some help
keeping the comments accurate and up to date.)  Imagine how many
tests we would need to write to provide the same level of coverage
for catching these kinds of bugs at compile time.

Are you suggesting this as an alternative to back-filling tests? Or just
in addition? Generally we should be adding tests for missing coverage of
functionality, static type checking won't get you everything. For
Firefox the general policy is to make sure changes to code are covered
by tests (so that we might eventually get good coverage everywhere).

Mark

Yes, yet another project that I really want to dig into but is on the back-burner behind other stuff that is more important right now. One of the things I'm hoping will happen which will make this even more valuable is a switch to using ES6 modules rather than our in-house JSMs which Typescript doesn't understand at all. Anyway, right now I don't really have a good summary of where this is at, just that it's something I'd love to have more time to work on. On Thu, Mar 21, 2019 at 2:50 AM Mark Banner <mbanner@mozilla.com> wrote: > We've looked at various options in the past, and none of them have > really fitted what we need. In the past, TypeScript also didn't support > JSDoc style comments at the time which didn't help (you had to do them > inline in function arguments etc). > > Dave also did some investigations in this area, and he can probably give > a summary better than myself. > > At the moment, I'm more looking to finish enabling ESLint everywhere, > and then getting a more consistent ruleset and enabling more rules. > We're also looking into set formatting of Javascript, in a similar way > to the clang-format effort that has been going on. > > > On 20-03-2019 14:44, Paul Morris wrote: > >> The more I think about this the more I like it. If we're going to be > >> writing JSDoc comments in any case, we might as well maximize the > >> benefits and get some static type checking out of it. (And some help > >> keeping the comments accurate and up to date.) Imagine how many > >> tests we would need to write to provide the same level of coverage > >> for catching these kinds of bugs at compile time. > > Are you suggesting this as an alternative to back-filling tests? Or just > in addition? Generally we should be adding tests for missing coverage of > functionality, static type checking won't get you everything. For > Firefox the general policy is to make sure changes to code are covered > by tests (so that we might eventually get good coverage everywhere). > > Mark > >