I've been doing TypeScript professionally for the last 8 months or so and I would like to push further my knowledge of the language by reading well documented and high profile app or packages. Any suggestions ?
The TypeScript compiler is the canonical corpus of code written by TypeScript experts, and I learned a lot of interesting style from the time I've spent with it. (Fun fact: they don't use 'class' in the compiler at all, but instead have a different pattern for passing around interfaces+state that is much more TypeScript-y.)
For better or worse? I've avoided classes in our codebase because I don't like the lack of privates via closure (revealing module pattern) and it's transpiler overhead, but it's a very powerful organization tool. I've found code to be much neater in the class format.
does anyone have some recommendation on how to debug typescript compiler, it seems like console does not work there, I am trying to just step through tsc.ts, but gulp local always complains that console is not defined. Is there any alternative in stepping through the compiler?
I second this. Not only is the code well-written, the whole codebase is architected in a modular and layered way. Many things are well documented. You can probably step up your game and write a plugin for VSCode as an exercise.
The VSCode codebase is evidence TypeScript is built to scale further then Javascript.
Its editor component "Monaco" is the single reason that TypeScript exists. TypeScript was created in conjunction with (or for) this first project, of course the editor was first used in other parts of MS, and only later was also integrated into VSC.
`!!x` is guaranteed to evaluate to a boolean value of `true` or `false`.
`if (x)` evaluates truthiness of `x` which in Javascript land might behave differently. I don't know how off the top of my head, but I know it's something to be cautious of in this language and its derivatives.
If there was a linter rule I could turn on to require booleans in if-conditions, I'd enable it.
`!!` might seem silly, but it's a hint that you intended for coercion to happen. A similar but better example would be preferring `if (x > 0)` over `if (x)` even though non-zero is truthy.
There's an even better case for returning `!!x` from a function even though you could return `x` and let the call-site coerce it. The problem with that is that the call-site can build a dependency on the value of `x` beyond truthy vs falsey.
In a weakly typed language like Javascript, I don't think you'll ever regret being a little more explicit.
> `!!` might seem silly, but it's a hint that you intended for coercion to happen.
"Silly" is in the eye of the beholder, of course. But it is definitely redundant. Using a value in an if statement is not just a hint, but an explicit guarantee that all you are doing with the value is testing it for truthiness. !! adds no information or insight that isn't already there.
> A similar but better example would be preferring `if (x > 0)` over `if (x)` even though non-zero is truthy.
Obviously you know this, but if( x > 0 ) is not the same thing as if( x ). You can't substitute one for the other: a truthiness test on x is different from testing the numeric value of x for being greater than zero. If x is -1, the two statements will do different things.
> There's an even better case for returning `!!x` from a function even though you could return `x` and let the call-site coerce it. The problem with that is that the call-site can build a dependency on the value of `x` beyond truthy vs falsey.
That's a completely different situation. When you return a value from a function, there is no guaranteed truthiness test as there is with an if statement. You're just returning a value "as is".
So for example, if you have a function that creates some private object and it's defined to return a truthy or falsy value to tell you if the object was created, it could be tempting to say "I have a variable with a reference to the object I'm creating or null if it failed. I can just return that variable!"
As you mentioned, the caller could hold a reference to that return value, thus holding a reference to the object that isn't necessary - and could lead to a memory leak. By using "return !! myObject;" instead, you avoid passing the object itself back to the caller and just give them a true/false value instead. This is a good thing to do.
But an if statement is not the same thing. The if statement already has a guarantee that all it will do with the value is test it for truthiness and not keep any reference to it. Adding !! doesn't convey any information to the reader that isn't already there.
I like being explicit too, but I don't like adding extra verbiage to something that is already completely explicit.
It doesn't play well with the vscode tslint extension for some reason (doesn't show up at all) so you need to run tslint manually to see the errors.. but it's better than nothing.
> In a weakly typed language like Javascript, I don't think you'll ever regret being a little more explicit.
"!!" is not needed in the shown case. It might be needed if you want to pass somewhere or return "boolean" value, but in the example it's only the "if" thing.
Opening the VS Code inside VS code? I would feel watched, like my VS Code is wondering what the hell I'm doing.
Is it not good enough for me? Is it failing me in some awful way that I feel compelled to change it? Maybe it should get out of the IDE business if its not good enough? Maybe become a farmer, take a break from technology
Or you can think about it as looking under the hood of a car, or taking apart an iPhone to appreciate the beauty. But I do love the irony. I imagine people have run binary decompilers on the decompilers themselves before.
I remember the tale someone fuzzing the same fuzzer to find bugs. I can't find the link though.
General tools like an editor, a decompiler, or even an image editor can be used to modify the software itself. After all, if you're the creator of the tool itself, most likely you feel comfortable using it.
What I always wonder is how people built the first tools. How did people compile the first version of GCC? How did people build the first programming language? How did people built the first OS?
I can imagine ways to solve these, but I guess the tale behind how they did it is what makes me wonder.
You could also search popular typescript github projects that are more closely related to what you work on, but the Typescript compiler and Babylonjs 3d engine are both well written projects with fairly good documentation in my opinion.
+1 for InversifyJS - I learned a lot of TypeScript by just reading through the actual Inversify codebase, and then used what I learned to write what would become https://github.com/inversify/inversify-express-utils.
Also, thanks to the Inversify contributors for continuing to maintain and improve express-utils!
+1 for InversifyJS from me too. I've also been looking at the inversify express utils lately -- loving it so far!
Do you know if there are any plans for allowing the http context (req, namely) to be injected into services? Similar to the IHttpContextAccessor in dotnet core?
I have some use cases for using pieces of the http context (headers) to instantiate some transient services. I started putting together my own pieces to see what I could get away with. Looks like it works okay, but I had to create a new container per request, using the `Container.parent` to link them.
This should be possible now. You can implement by yourself as described at https://twitter.com/RemoHJansen/status/927542673682116611. I have already started to think about a way to add this into the inversify-express-utils but I have to think it well so it can support all kinds of auth.
That's cool but surely any implementation of a language in itself is going to deal with some pretty fringe situations, so it might not be the best thing to read in order to learn how you should write other things in that language?
There's no reason why implementing a language in itself would be special, it's not dealing with fringe situations in any sense of the word. It is traditional to write compilers in the very language they compile, except for slow interpreted languages, and a compiler is a very well-studied type of program that includes a variety of different types of code such as straight text processing, error reporting, and recursive data structures. Compilers are often used as test beds for new language features, famously, Niklaus Wirth would measure language improvements based on how much they would improve the language's compiler.
Think about it this way: a TypeScript compiler takes a bunch of text as input, and produces a bunch of text as output. That's not really special or weird, is it?
(The only hard part is the “bootstrapping problem” which is what happens when you want to write a compiler for language X using language X, but you can’t compile it because you don’t have a compiler yet.)
a TypeScript compiler takes a bunch of text as input, and produces a bunch of text as output. That's not really special or weird, is it?
In the case of a compiler used for production, it may have lots of optimizations, most of the time, this optimizations are non-idiomatic code that's hard to understand and its purpose its not obvious.
Can you give an example of this? Most of the compilers I've seen have excellent code bases, with good separation between the different components, probably because compilers are so well-studied. It can be surprising what the most productive part of the compiler is to optimize. Often the lexer is heavily optimized due to its outsized impact on performance, but even then, the code looks idiomatic to me.
Interested in that bootstrapping process. Is it just that the first version has to be compiled with some other language. From then on, you just use the previous version that you have compiled already?
Yes, that is normal. If you can imagine, this process dates back to the first assemblers, which were written in assembly and then converted by hand to machine code.
From what I recall, start by writing a minimal compiler for language X in some other language, Y, and compile it. Now you have an X-compiler written in Y.
Rewrite the minimal compiler in X, and compile it using the one that was written in Y. That gives you an X-compiler written in X compiled from one written in Y.
To be sure _that one_ works, recompile your X source code with that last compiler. Now you have a compiler written in X and built with one also written in X.
Continue to add more features written in minimal-X to get X-compilers with more X features.
Just as small improvement, for the first step an interpreter is a better approach, just to ease the bootstraping process by not having to write a compiler backend twice.
Exactly what I was thinking while browsing the code. In particular, I'm looking for the "right way" to code the application. Using Observable, Promise, patterns, etc. To get to the point that I don't ask myself all the time if it's the right way to do the things.
A caution: I’ve observed a lot of code that’s been damaged by enthusiastic use of patterns or library features, and I’ve met novice programmers who doubt whether their code is good code based solely on the fact that it doesn’t use Observable, Promise, patterns, etc.
Look for code that is correct, clear, concise, testable, etc.
It's also one of the larger enterprise grade projects that i've seen done natively in TS. It pretty much uses all the bells and whistles that the language provides. Some decent patterns, and an active developer community.
A little off topic, but is anyone using this in a large production environment? I'm currently using sequelize for a side project and haven't been terribly happy with it. TypeORM looks better but it feels like it has just sprung out of nowhere and is maybe too new to use in the real world.
No specific education, just jump in and follow existing patterns. Most devs we hire pick it up quickly and we have people here that can help with more complicated questions. We have a few people who really grok the type system and can help with nasty type issues when they come up.
And what about the "TypeScript Design Patterns" book, you guys have read it ? Is it good ? Is it worth the investment ? http://amzn.to/2ym40AW And what about Online Courses on Udemy?
My favorite is finding the libraries that now have typings (they migrated to TS themselves or got a good definition PR they accepted, maybe even a PR you sent the library directly), and sending the removal PR to DT. DT is huge so every file that can be removed is a little bit less of a papercut in checkout time and testing time for the next branch/developer.
and please break the codebase of people using these types by not following semver (keeps happening to me with typings -_- should really start using a lock file)
I have a huge blob of old JavaScript cellular automata code I want to rewrite in TypeScript, but first I want to read some good TypeScript code before starting so I don't mess it up.
It has a bunch of old "frameworky" meta-programming code and data structures that I've painted myself into a corner with (see the "type definitions" comments), which I'd like to throw away and re-implement from scratch, because TypeScript is much better suited for that kind of stuff. And then there's a bunch of brute force bit bashing and number crunching code that I hope will just run without any modification and only a little repackaging, which is another nice benefit of TypeScript.
If you're going to be doing React - the Blueprint source
(Palantir's react ui kit) seems to be really well written. I don't work there... I just use it.
I would take an existing vanilla JS project if you have one, and convert it. I learned a lot there. You can also learn a lot of the conventions by using/studying TSLint. https://github.com/palantir/tslint
Depends. How good are you at JS? Because I think learning what great JS looks like will give you a better grounding in what TS is actually adding to JS and what is “good TS” vs “good general practice”.
That might sound dismissive of TS but it’s not, I’m just trying to get a sense on what you’re trying to learn from TS.