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