
Show HN: Boilerplate for Node.js and TypeScript with Jest tests - jsynowiec
https://github.com/jsynowiec/node-typescript-boilerplate
======
pyrophane
I built a non-trivial webapp in nodejs + Typescript but abandoned it due to
these issues:

1\. You can generate source maps for your TS files, but node can't use them.
There is some support for source maps via the node-source-map-support, but it
doesn't play well with a lot of stuff out of the box. Just getting accurate
stack traces in my logs turned into a project of its own.

2\. Most node libraries don't include type definitions, and what is on
DefinitelyTyped is more likely than not to be out-of-date and inaccurate.
Having the wrong type definitions might be worse than none at all, which means
for the most part you'll be declaring a lot of stuff as "any." It makes even
preserving the types in your own code difficult, as anything that touches a
3rd-party library is going to come back as the any type without additional
annotation.

3\. Similar to 2, if you want to use a promise-based approach to deal with the
"callback hell" induced by node's continuation passing style, you are probably
going to need to use a library that does runtime mutation of the many
libraries that don't support promises, which means that any time information
you do have about 3rd-party libraries is going to get lost.

4\. The last two items, combined with the lack of runtime type checking, means
that your types are going to be difficult to maintain and can easily become
inaccurate without feedback from the compiler to let you know that something
is wrong.

~~~
jsynowiec
Re 1: This is not a problem with TypeScript, but with Node. It's the same with
every to-js-transpiled language. You can use [https://github.com/evanw/node-
source-map-support](https://github.com/evanw/node-source-map-support) to get
stack traces for your TS sources.

Re 2: I do agree that this is a problem but remember that it's all just a
community effort. You can always create your own type definitions or enhance
existing ones and share on the DefinitelyTyped repository. Also, most of the
time if a type definition is out of date or invalid, you can just create your
own partial typedef for a module with only those several methods you are
actually using.

Re 3: IMO it's a feature. By using, for e.g. a bluebird library to wrap third
party code in a Promise, you are changing the way how your code is interacting
with that library by redeclaring the whole library or some parts of it. TSC is
complaining because you've changed the declarations. You have to provide your
own type definitions, either inline, or for the whole module.

I've engineered or reviewed several projects that are using TypeScript with
success. The teams after initial hiccups are mostly not willing to come back
to _pure_ JavaScript now.

I'm not advocating to use TS everywhere and for every project. It all depends.
Many factors must be considered but some sort of type checking is usually a
good thing to have.

~~~
pyrophane
Yea, I didn't really mean for my comment to be a criticism of Typescript
itself, but rather I wanted to explain some of the difficulties I have
encountered trying to use it on a large node project.

Per your follow-up comments:

1\. Have you gotten node-source-map-support to work with a logging framework
like Winston that handles uncaught exceptions? It didn't work out of the box
for me, but I'm sure that with some effort it could be made to work.

2\. Yea. I think a big part of the problem is that even a lot of very popular
node libraries just aren't that stable. APIs change a lot and the
documentation is poor, so keeping a type definition up-to-date and accurate is
particularly difficult.

3\. I agree that that is by design, but that doesn't make it any less of a
barrier to using promises across an application that depends on a lot of 3rd
party libraries, and as a developer I don't want to have to spend a lot of my
time maintaining type definitions to work around it in my project.

I agree that having used Typescript I would not want to move back to plain JS,
but for me the experience pushed me away from using node as a backend in the
future, as I think there are other platforms that provide the same benefits
without the drawbacks and difficulties.

~~~
bengalister
I am just curious, which platforms do you think provide the same benefits
without the drawbacks ?

------
vnglst
Question for the poster: any general thoughts on why you chose TypeScript
instead of Flow Type?

~~~
jsynowiec
I'm using both TypeScript and Flowtype for my projects, hence the second
boilerplate repository on GitHub: [https://github.com/jsynowiec/node-flowtype-
boilerplate](https://github.com/jsynowiec/node-flowtype-boilerplate)

Usually I tend to lean towards TypeScript due to:

\- Much better tooling and editor/IDE integration (I'm using vscode and
WebStorm),

\- DefinitelyTyped repository and the availability of type definitions,

\- It's subjective but TS has better documentation and examples,

Don't get me wrong, the Flow (and React) community is doing a great job and in
my opinion Flow is a very good tool for static type checking. The real problem
with both is the coverage/quality of type definitions and the amount of time
it takes to create typedefs. Right now there are many more typedefs available
for TypeScript and the community is stronger and more active.

Also, right now one common format or conversion between definition formats is
not possible, see:
[https://twitter.com/lbljeffmo/status/787692583350829056](https://twitter.com/lbljeffmo/status/787692583350829056)

~~~
vnglst
Awesome, thanks!

------
vnglst
"Unit tests in JavaScript

Writing unit tests in TypeScript can sometimes be troublesome and confusing.
Especially when mocking dependencies and using spies."

Anybody know why unit tests are difficult in TypeScript?

~~~
Joeri
Typescript is strictly typed, so things that need to look like a type but
aren't actually that type, like mocks and spies, can be troublesome.

~~~
jsynowiec
Exactly. TSC usually complains on all stubs, mocks and spies or it takes
massive amounts of time to properly annotate the types. Unit tests quickly
don't follow AAA rule, are hard to read (and understand) and the required time
investment is not worth it. I find using TypeScript for source code and
JavaScript for unit tests much more convenient.

~~~
scoti
I had the same problem until a recent TS release introducing the keyof
feature. You can create a TypeScript type that automatically convert a class
definition to stubs.

    
    
      type StubInstance<T> = {
          [P in keyof T]: sinon.SinonStub;
      };

------
roboguy12
FWIW, Typescript also has async/await, as of 2.1 (in reference to the
Alternative section in your README).

~~~
jsynowiec
The alternative refers to an alternative type checking system - Flowtype. Not
that the seconds has the async/await and modules. Both repositories are trying
to deliver quite similar tools - type checking, es6 + async/awat + import
syntax and linter.

------
elvinyung
Serious question: Is Node.js still a popular choice for developing webapps?

I thought that has stopped being true for a while now.

~~~
pyrophane
Comments such as this one read to me as a dig at a particular technology the
commenter does not like. Sort of a more subtle version of "Oh, I didn't
realize people were still using THAT."

~~~
elvinyung
I'm sorry -- it was not intended to be condescending. I really haven't heard
much about Node.js for some time, and it's actually really hard to figure that
out.

