August 27, 2019

Modern JavaScript TypeScript

by Dave Sweeton

Modern JavaScript TypeScript

How far we’ve come!

Back in the day, JavaScript was the nightmare language that no one wanted to use—partly due to its quirks and mostly due to terrible competing browser ecosystems.

It got better with JQuery, which fixed the latter problem by making it easier to access the browser's DOM in a (mostly) uniform way. JQuery also made a nice platform for adding UI components and 3rd party plugins.

Then in 2009 and 2015 new versions of the JavaScript standard were released that improved some of the quirks and added new language features.

Fast forward to today. Some developers choose JavaScript for full stack—that is both server and client development.

I’m not there yet. I use JS a lot, but still prefer something statically typed on the back-end.

For similar reasons, I actually prefer TypeScript over JavaScript on the front-end. TypeScript gives you two benefits:

  1. Types. As you can guess from the name, TypeScript lets you annotate types to get some static compile-time type checking. It’s just an annotation/hint though (since JavaScript itself is still dynamically typed), but I find it more helpful than I do annoying (most of the time; sometimes it gets in your way, and you want to bail out by casting to “any”).
  2. Language features. TypeScript is on the vanguard of adding new language features, sometimes getting them before they are added to JavaScript itself. Since Typescript requires a transpiler (see below), it has more freedom to add features than JavaScript does.

If you aren’t doing modern JavaScript or TypeScript, here’s a whirlwind primer of concepts and features you need to know.

Transpiling

Most of my JS work targets the browser, which means I need to target old JavaScript standards (though for most clients I no longer support Internet Explorer!). This isn’t a limitation, but it does mean that you need an extra build step to convert your new JavaScript/TypeScript to something the browser can understand. Enter the transpiler, which is similar to a compiler except it converts one programming language to another programming language (instead of to machine language). Babel is the most popular option for JavaScript, but for TypeScript you just need TypeScript itself. (It is a transpiler.)

Polyfill

Polyfills are essentially code or libraries that "patch" older browsers to provide language features that are part of newer JavaScript. Modern browsers provide these features out of the box, in which case the polyfill does nothing.

Many helpful functions have been added, even to basic things like Arrays and Strings. I love using Promises for all of my development. Promises are features for doing asynchronous programming. Basically they encapsulate a task, like make a web request, and allow you to add callbacks that will be notified when the task completes in the future. Mozilla’s Developer Network is still the best reference for what’s available and on what browser versions (and it usually has polyfills too): https://developer.mozilla.org/en-US/docs/Web/JavaScript

Libraries

I'm not sure how you'd do modern JS development without 3rd party libraries, and there are a number of ways to get them and manage them. Some popular options are NPM, YARN, and Bower. They work similarly to Nuget in the .Net world; they provide a huge repository of versioned libraries and ways to install them and track them (so other developers on the team get the same versions). If you don't have a package manager, I'd default to NPM. It is popular and well supported.

One thing to be aware of is the need to update packages regularly. This isn't unique to JavaScript or NPM, but it is a bigger concern here because of the sheer number of dependencies. (Many libraries use other libraries that use other libraries.) Remember that the Equifax data breach was caused because they failed to update a 3rd party library! (Though it was Java in their case, not JavaScript.)

Language features:

Here are some of my favorite every-day-can’t-live-with-out-them language features. Note that most language features I’m talking about are not TypeScript specific but are actually features from newer versions of JavaScript (or ECMA script as it’s officially called by no one). Since I mainly use TypeScript, I’m not usually aware of what features are coming from TS or JS.

My list targets TypeScript, and may also apply to JavaScript:

Classes & Constructors: Yes, they just paper over JavaScript's confusing prototypical inheritance model, but still they are great to use, even for readability alone. TypeScript has support for inheritance (“extends”) as well as public/protected/private accessibility modifiers that do what you would expect.

Interfaces: TypeScript only, since they are only used for typing, but they help make API function calls easier to use, while still supporting JavaScript’s dynamic duck-typing.

Arrow functions: AKA delegates, functors, and inline functions. Being able to write inline functions with

(incrementMe) => incrementMe +1

is a tremendous improvement over JavaScript’s wordier functions, especially when using a more functional style of programming (like Array.filter, Array.find and Array.map). Code is much more concise and readable!

Improved "this": JavaScript is notorious for its confusing and bug inducing use of “this.” (Why it is confusing would take an entire article. Fortunately the Internet is full of them.) Arrow functions capture “this” and generally do what you would expect. You still have to be aware of the “this” issue, but it crops up way less often.

Variable scoping: JavaScript is also notorious for confusing variable scoping. If you switch to “let” instead of “var” to define variables, then suddenly JavaScript works like every other language. It takes some retraining to form the new habit, but it’s painless and free.

Const variables: Instead of “let” you can use “const” to define things that don’t change. Note that it is the variable that doesn’t change, not the thing that the variable points to (which you can still mutate). Not as powerful as a full C++ style const implementation, but still useful, and enforced by the (TypeScript) transpiler or runtime.

Destructuring: Frequently, when passing an object around you want to pluck out and use just a few properties of that object. TypeScript makes that super convenient:

let { a, b, c} = someObject;

This is equivalent to the following:

let a = someObject.a;

let b = someObject.b;

let c = someObject.c;

You can even use destructuring for function parameters so ({value}) => alert(value); takes an object with a member named value and automatically pulls it out into a variable of the same name. This is great for event handlers!

Object construction: There’s also a similar syntax for creating objects. The output from

const a = "hello"; const other = "world";
let output = {a, b: other};

is an object with a field named “a” that has the value “hello” and a field named “b” that has the value “world.” This syntax is confusing when you are first introduced to it, but it’s easy to read after you understand it.

Spread operator: JavaScript supports a new . . . operator that spreads out an object or an array. This can be used to spread out an array of arguments to call a function rather than using .apply(), but I love it best for cloning arrays and objects.

const theClone = {...Source, age:10}

This creates a new object (theClone) that contains a shallow copy of the members from Source, with an age field that has a value of 10. If Source has its own age property, it will be overridden by the new value. This is equivalent to manually setting all of the fields of Source into a new object, but so much easier and more versatile. (I don't need to know the fields of Source ahead of time.) It also handles Source being null/undefined. The same syntax works with arrays, and both are a great help for working with immutable data (which is a very helpful paradigm for simplifying reactive data updates).

Import/export: JavaScript now supports proper import/exports for sharing types and functions between code files. This change alone cleans up your codebase by fixing collision issues and allowing you to "hide" internal implementation details, by only exporting things that form the API you want to support.

Generics: TypeScript has full support for generics in type definitions, and they work exactly as you'd expect.

Enums: TypeScript supports full-fledged enumerations based on either numeric values or strings! Much nicer than hardcoding strings or even using exported const variables.

Async/await: I love Promises for asynchronous programming. I've recently started using async/await in TypeScript, which are easy to use and work exactly the same as the C# equivalents. (It is great to have such a nice parallel when working on the .Net tech stack.)

Summary

There are many more great features of TypeScript (and new JavaScript), and new ones are added regularly. The nice thing, though, is you can learn them as you need them. You can start off writing plain JavaScript in .ts files, and just improve it and add new features as needed.

TypeScript works well with React, Vue.JS, and is mandatory with Angular. It's easy to integrate into existing projects alongside legacy code (though it's easier to call JS code from TS than the reverse depending on your transpiling setup). TypeScript works with all existing JavaScript libraries, and many have type definitions available specifically for TypeScript, so there's very little reason not to use it. The only real downsides are the extra cognitive load of learning it (just learn it as you go), and the extra build process (vastly paid back by developer productivity).

Stout Systems is the software consulting and staffing company Fueled by the Most Powerful Technology Available: Human Intelligence®. Stout was founded in 1993 and is based in Ann Arbor, Michigan. Stout has clients across the U.S. in domains including engineering, scientific, manufacturing, education, marketing, entertainment, small business and, yes, robotics. Stout provides expert level software, Web and embedded systems development consulting and staffing services along with direct-hire technical recruiting and placements. If you're looking for a job in the tech industry, visit our job board to see if you qualify for some of our positions. Best of luck to you! If you're looking to hire technical talent for your company, please contact us. This is a technical article catered to developers, technical project managers, and other technical staff looking to improve their skills. Sign up to receive our technical articles in your email inbox.

info@stoutsystems.com
877.663.0877
© Copyright 1995-2019 - STOUT SYSTEMS DEVELOPMENT INC. - All Rights Reserved
envelopephone-handsetlaptop linkedin facebook pinterest youtube rss twitter instagram facebook-blank rss-blank linkedin-blank pinterest youtube twitter instagram