Things I found great about TypeScript that D could benefit from
w0rp
devw0rp at gmail.com
Fri Apr 27 19:17:14 UTC 2018
Hello everyone! I haven't written a post in a long time. I love
D, and I've been a D hobbyist for years now. Though I haven't
written any D in a long time, I keep an eye on the changelogs and
such. More recently I've been using TypeScript (TS) at work for
front end code. TypeScript is a very different kind of beast,
compared to D, but there are some features in TypeScript I now
use every working day which have really improved the quality of
the software that I write, and I'd like to share my thoughts on
them. I'll explain a few things and then say what I think D could
learn from TS.
The first feature I found really useful is the --strictNullChecks
option that TypeScript has. I hate null dereferencing errors with
a passion, and they have been the number one source of bugs that
I've seen. The TS type system with the option off effectively
treats `T` as `T | null | undefined` with the option off, and
excludes `null | undefined` with the option on, meaning it forces
you to check for `null` or `undefined` where such values are
possible, according to the type system.
What I found really interesting is that TS implements null
checking not through more traditional means like a "Maybe" or
"Option" monad, but through typical syntax. If you write `if (x
!= null) { }`, then TS narrows the type from `T | null |
undefined` to just `T` inside of that if statement. This also
works for more complex syntax, such as breaking a loop, returning
early if something is null and pressing on if it isn't, inside
expressions like `x != null && x.y`, and so on. I could never get
colleagues on board with changing all of their code to use
Maybe/Option types, but this kind of syntax is something they
don't even have to think about.
The second feature I found very useful is that TS uses
"structural typing." You declare an interface with some
properties, and any object which matches those properties is
considered to be of that type. Meaning that TS doesn't care what
the "class" or prototype of your object is, just that has the
right stuff in it. This is essentially statically-checked duck
typing. There is some algebra on types, so you can write `T & U`
for something with the properties of types `T` and `U`, or `T |
U` for either.
What's very powerful about unions in TypeScript is that it
automatically determines which fields can be used as tag
attributes for tagged unions. This means you can declare tagged
unions without thinking about writing a very specific tagged
union type, and without using a special tagged union type. This
largely works because of the nature of TS's basis on top of a
dynamic type system where attribute lookup is all virtual.
The third big feature I'll end on is just the quality of the
tooling. There's great code completion, tools for fixing bugs,
pretty good diagnostics, a protocol like LSP I integrated into
Vim, etc. They have done a pretty good job of getting the tools
right.
What I think D could learn is pretty much...
* Strict null checking is a winner, and you can use ordinary
syntax to handle this.
* Writing `(InputRange r)` instead of `(T)(T r) if
(isInputRange!T)` would be a nice improvement, and writing
something like this hypothetical `InputRange` concept could be a
lot easier, somehow. (C++20 might finally include concepts.)
* Good tooling makes everything better. Keep on working on good
tools for D.
That's it, let me know your thoughts.
More information about the Digitalmars-d
mailing list