Typing Arrays in TypeScript

There are many ways we can type a property to declare to TypeScript something is an array, or contains an array of “something”. We have generic types, array types and type assertions.
For the purposes of this article, we’ll simply use a TypeScript class to demonstrate how we can declare some of these properties, in the various forms.

Table of contents

Type Inference
Declaring an Array Type
Using Array Generic Types

Type Inference
Before we explore the benefits of explicit typing, let’s consider a class with an array. This will infer the type of an array:
// inferred as messages: any[]
class Chats {
messages = [];
}

And we can again, infer:
// inferred as messages: number[]
class Chats {
messages = [1, 2, 3];
}

We can of course mix and match our types, and TypeScript will infer as best as possible:
// inferred as messages: (string | number)[]
class Chats {
messages = [‘A’, ‘B’, 1, 2];
}

This is great for well defined APIs, return statements and such that we are fully confident we want to infer. So let’s explore the main ways we can type an array in TypeScript.
Declaring an Array Type
Before we continue, let’s introduce a second class member, the single Message:
class Message {
constructor(private from: string, message: string) {}
}

// create a new message
new Message(‘Todd Motto’, ‘Hey, you around?’);

Our Chats class can now be sensibly typed like so:
class Chats {
messages: Message[] = [];
}

We assign what looks like an array, but we know it’s a type as we’re using : before the array assignment. Interestingly, outside of the array [] type, we specify what the array contains, i.e. Message[].

Learn more about using Classes as Types here!

In this case, we’re expecting only an array of messages.
We could in fact just declare the properties on the class, and assign the property’s value perhaps in the constructor.
class Chats {
messages: Message[];
constructor() {
this.messages = [];
}
}

In Angular, this is typically done inside the ngOnInit lifecycle hook:
class Chats implements OnInit {
messages$: Observable;

constructor(private store: Store<State>) {}

ngOnInit() {
this.messages$ = this.store.select(‘messages’);
}
}

A more comprehensive example, but we digress. However – you may have noticed Observable<Message[]>. Have you seen this before? If not, let’s explain because the same principle applies when typing arrays.
Using Array Generic Types
Generic types in TypeScript are essentially ways to make things more… generic.
Generics are parameterised types, where we can either let TypeScript infer the type for us, or we can specify it ourselves. Using a generic type in TypeScript alongside an array looks like this (which is the equivalent to what we’ve covered above):
class Chats {
messages: Array<Message> = [];
}

There’s no functional difference between using a generic instead of a normal typing, however depending on your use case and complexity of types – you may wish to opt for one over the other.
Another nice thing about generics is that we can combine initialisation and also infer the type, creating a new array whilst passing the generic type:
// inferred as messages: Message[]
class Chats {
messages = new Array<Message>();
}

So, why do we have multiple ways to declare an array? TypeScript is pretty wild at times, and we have many ways to do things – TypeScript provides us a lot of options alongside that.
There are actually a few more ways to type an array as well (but I’d stick with the things we’ve covered above for sanity):
// I’d go for this option
class Chats {
messages: Message[] = [];
}

// Looks a little more oldschool, but same as above
class Chats {
messages: Array<Message> = new Array();
}

// Don’t do this unless you need to assert the type
class Chats {
messages = [] as Message[];
}

// And really, don’t do this
class Chats {
messages = <Array<Message>>[];
}

As the saying goes, “A typed array keeps the errors away”…
Okay that was terrible. Be smart, type your code and enjoy!

Link: https://toddmotto.com/typing-arrays-typescript

Introduction to TypeScript

Since its inception, JavaScript has experience monumental growth.
The language has expanded its application domain far beyond the browser. It is now used to power up backends, create hybrid mobile applications, architect cloud solutions, design neural networks and even control robots! The versatility of JavaScript paired with its high adoption rate has created an increasing demand for scalable, secure, performant and feature-rich JavaScript applications, which in turn has created a need for tooling, libraries and frameworks that make it easier and faster to write applications that meet those expectations.
This demand for high performance JavaScript led to the introduction of TypeScript.
Let’s explore in detail what are the design goals and benefits that using TypeScript brings to any codebase – from a small side project to a large enterprise one.
If you’d like to learn more about TypeScript, come and join me over at Ultimate Angular to take a deep dive – and grow your skills!

Table of contents

TypeScript is a Superset of JavaScript
TypeScript Architecture: Design Goals
JavaScript Compatibility with TypeScript
Giving Type Check to JavaScript
More Powerful JavaScript Object Oriented Programming
Zero Overhead

TypeScript Architecture: Components
Language
Core TypeScript Compiler
Parser
Binder
Type Resolver or Type Checker
Emitter
Pre-processor

TypeScript Standalone Compiler, tsc
Language Service
Tool Integration

Setting Up and Using TypeScript
How to Install TypeScript
Create a TypeScript File
Compile TypeScript
Configure TypeScript using tsconfig
TypeScript Playground
Conclusion

TypeScript is a Superset of JavaScript
TC39, the committee that regulates the development of JavaScript, has introduced new features to the language with each release version. Recently added features such as classes and block-scoped variables make standard JavaScript more robust. However, the language can be further enhanced and hardened to handle highly complex architectural demands in a reliable and predictable way. TC39 oftentimes has features in its pipeline that would help achieve that architectural goal but it takes time for them to become part of the standard language and to be supported by all major browsers.
As each new version of JavaScript extends the previous one, we could think of “Future JavaScript” as a superset of the current standard one. With that model in mind, TypeScript was created to act as that superset of JavaScript that puts the future of the language in the hands of today’s developers. Moreover, TypeScript integrates features outside of the scope of TC39, such as type-checking, generics and interfaces, that mitigate many points of failure present in JavaScript and rev up development – all provided through abstractions written in JavaScript. All that TypeScript gives you is convenient syntactic sugar that eventually gets all converted to cross-platform JavaScript.
Let’s explore in detail the architecture and components of TypeScript to understand its benefits deeply.
TypeScript Architecture: Design Goals
Microsoft designed TypeScript with specific architectural parameters in mind that allow TypeScript to integrate fully and easily with existing JavaScript code while providing robust features external to JavaScript.
JavaScript Compatibility with TypeScript
As we’ve established, TypeScript is a superset of JavaScript. This relationship permits TypeScript to understand and work with any code that is valid JavaScript. Any valid JavaScript code is valid TypeScript code with only a few exceptions: handling option function parameters and assigning a value to an object literal.
Do take note that valid TypeScript is not valid JavaScript code. TypeScript contains syntax and abstractions that do not exist in JavaScript and using them with JavaScript would generate JavaScript runtime errors. However, in an effort to promote compatibility, TypeScript developers align the language with the pipeline of ECMAScript. Current and future ECMAScript proposals are considered when designing new TypeScript features.
Giving Type Check to JavaScript
JavaScript being a loosely typed language is extremely lenient on the value assigned to its variables and it creates no structural contracts of any kind between those variables and the constructs that use them. Passing a number argument to a function that expects a string parameter generates no errors in JavaScript during development but will create havoc during runtime when the body of the function is not able to use that argument correctly.
To prevent these runtime issues, TypeScript was designed as a strongly typed language that performs static type-checking during its compilation time to JavaScript. For flexibility, the type-checking capabilities of TypeScript are optional; however, most of TypeScript key benefits revolve around type-checking – it’s the main reason to use TypeScript! For example, type-checking lets the language service layer of the language to be used for creating better tools that maximize your productivity while reducing the instance of errors.
More Powerful JavaScript Object Oriented Programming
The syntactic sugar provided by TypeScript will allow us to reduce the footprint of our code significantly while increasing its expressiveness. TypeScript makes writing class object-oriented code a breeze. It provides us with classes, interfaces and modules that allow us to properly structure our code in encapsulated reusable structures that makes it easy to maintain and scale. Within classes, we are also able to specify the visibility level of class properties and methods by using TypeScript provided modifiers – public, private and protected. There are many other abstractions that will make us happy and productive developers!
Zero Overhead
As TypeScript developers, we work in two different contexts – design and execution. In the design context, we use TypeScript directly to write our application. Now, since TypeScript is not supported by any browser, in order to make our design code work, it has to become JavaScript code. In the execution context, all of our TypeScript code is compiled into JavaScript code and is then executed by its target platform – the browser for example. The browser has no clue that this code is compiled – it looks just like the plain JavaScript it knows how to execute. Therefore, TypeScript imposes no runtime overhead on any application.
For the browser to receive valid execution code, the TypeScript compiler takes TypeScript features and implements them in whatever JavaScript compile target of our choice – we can go as early as ES3! As we know, there are some TypeScript features that simply do not exist in JavaScript and cannot be implemented, such as type-checking and interfaces. These unsupported features are simply removed from the compiled code – this is known as type erasure. Their removal has no impact on the functionality of your code because these unique features are there only to help TypeScript enhance your developer experience and they don’t overrun or override anything core to the JavaScript language.
TypeScript Architecture: Components
The architecture of TypeScript is neatly organized in different layers.
Language
Core TypeScript Compiler
Sometimes called the TypeScript transpiler, the TypeScript compiler has the core task of managing the low-level mechanics of type-checking our code and converting it into valid JavaScript code. The compiler uses static code analysis to mitigate the occurrence of runtime errors. Typos in our code or passing the wrong type of argument to a function will make the compiler throw compile-time errors to warn us that something is wrong before we even execute the code. This is extremely valuable as, even with the most comprehensive suite of tests, logic errors and edge cases can crash our application at runtime. TypeScript ensures that type definitions that we create within our code are used consistently throughout it.
The compiler itself is made up of different parts that work together fast to make our code predictable and to compile it:
Parser
A quiet complex yet critical component that takes input data, our TypeScript source files, and builds a data structure from it – in this case, an Abstract Syntax Tree. Parsing our code creates a structural representation of the sources that allows us to check that they are following the language grammar – that is, that the sources are built using the correct syntax.
Binder
When we have, for example, a function and a module with the same name, the binder links these named declarations using a Symbol, allowing the type system to make sense of them.
Type Resolver or Type Checker
This component resolves types for each construct, checks semantic operations and generates type diagnostics.
Emitter
Generates output from .ts and d.ts files. The output can be either a JavaScript file (.js), a TypeScript definition file, (d.ts), or a source map file (.js.map).
Pre-processor
Resolves and manages references amongst files using import or /// \.

We will learn in an upcoming section how to setup and configure the TypeScript compiler.

TypeScript Standalone Compiler, tsc
We’ll shortly explore the installation and usage of the standalone TypeScript compiler. Referred to often as tsc, it is a high-level compiler that takes a TypeScript file, .ts, and outputs a JavaScript file, .js.
Language Service
This component layer sits on top of the core TypeScript compiler and provides features that are needed for IDEs and text editors to do their job, such as statement completions, signature help, code formatting and outlining, syntax highlighting and many more. The language service also powers code refactoring such as renaming variables, debugging and incremental compilation.
Tool Integration
TypeScript offers type annotations that allow IDEs and text editors to perform comprehensive static analysis on our code. These annotations allow these tools to make smart suggestions by making our code far more predictable. In return, IDEs and text editors can offer better auto completion and refactoring of TypeScript code.
Setting Up and Using TypeScript
How to Install TypeScript
The easiest way to get TypeScript up and running is by installing its standalone compiler (tsc) globally via a Node.js package manager such as npm or yarn.
npm install -g typescript

or
yarn global add typescript

Once this global installation of the TypeScript compiler is complete, we have access to the tsc command from our terminal that allow us to compile .ts files into .js ones. We can verify the success of our compiler installation by running the following command to check its version:
tsc -v

The TypeScript compiler comes with many options that we’ll be exploring as we move forward. For now, create a folder anywhere in your file system called ts-intro. We are going to use that folder to store our TypeScript source files and take it for a spin!
Create a TypeScript File
Using a text editor, IDE or terminal – whatever option you prefer – create a file named barista.ts. Within our file, we are going to create a barista function that takes name and outputs an order call using that name:
// barista.ts

function barista(name) {
console.log(‘Peppermint Mocha Frappuccino for ‘ + name);
}

let customer = {
name: ‘Todd’,
};

barista(customer.name);

We’ve created a valid TypeScript file but how do we run it? Let’s do that next.
Compile TypeScript
With our folder ts-intro as our current directory, let’s execute the following command in our terminal window:
tsc barista.ts

We get barista.js being added to our folder ts-intro – this is the output of the compilation. Open barista.js and notice that it’s almost exactly the same as barista.ts:
// barista.js

function barista(name) {
console.log(‘Peppermint Mocha Frappuccino for ‘ + name);
}
var customer = {
name: ‘Todd’,
};
barista(customer.name);

One way to quickly spot what changed through compilation is by running a difference on the content of both files:
OSX / Linux: diff barista.ts barista.js
Windows: FC barista.ts barista.js
The file difference is nothing major. tsc changed the scoped variable let to var. This happened because the default target JavaScript for compilation is ES3 – which doesn’t support let. We’ll learn soon on how to modify the compiler configuration. We can now run barista.js through node by executing the following command:
node barista.js

As it is, barista.ts has no TypeScript on it, hence, there’s not much to compile. Let’s add more TypeScript features to it to see a more dramatic file change.
Let’s drastically modify the code by creating a Barista class that has a static method that calls the order and uses type annotations to enforce type checking of our variables:
// barista.ts

class Barista {
static callOrder(name: string) {
console.log(‘Peppermint Mocha Frappuccino for ‘ + name);
}
}

let customer = {
name: ‘Todd’,
};

Barista.callOrder(customer.name);

Because callOrder is static, we do not need to create an instance of the class to be able to use the method. Much like Array.from, we call the method from the class name itself. Compile the code running tsc barista.ts again and note how this time we get a quite different barista.js:
// barista.js

var Barista = /** @class */ (function() {
function Barista() {}
Barista.callOrder = function(name) {
console.log(‘Peppermint Mocha Frappuccino for ‘ + name);
};
return Barista;
})();
var customer = {
name: ‘Todd’,
};
Barista.callOrder(customer.name);

ES3 supports no class construct, therefore, this TypeScript construct has to be implemented in plain JavaScript. Notice, however, how nice and readable the compiled code is! The compiler created a comment annotation, @class, in the JavaScript file to denote Barista as intended to be a class – increasing our code readability.
Configure TypeScript using tsconfig
Much like package.json is added to give npm instructions on what packages to install as project dependencies, we can use a tsconfig.json file to provide instructions on how our TypeScript project should be configured. Adding tsconfig.json to ts-intro marks the folder as the root directory of our TypeScript project. In this file, we can specify compiler options to compile our .ts files as well as root files for our project.
Create a tsconfig.json file within ts-intro with the following configuration to tell the compiler to use ES6 as the JavaScript compilation target instead:
{
“compilerOptions": {
"target": "es6"
}
}

From now on, whenever we run the tsc command, the compiler will check this file first for special instructions and then proceed with compilation based on those instructions. It’s important to know that to make use of tsconfig.json, we do not specify any file inputs to tsc. To compile barista.ts once again under this new configuration simply run the command tsc in your terminal.
Since we are using ES6, which supports class, as the JavaScript compilation target, barista.js doesn’t look very different than barista.ts! The only difference is that the compiler removed the code related to static type checking. The name argument doesn’t have any annotations to indicate its type since this feature is not part of ES6.
There’s a much easier way to initialise a TypeScript project and create its tsconfig.json file. We can use a handy shortcut similar to what’s done to kickstart a Node.js project. Let’s go ahead and delete the tsconfig.json file that we created and then run the following initialisation command:
tsc –init

The output of running this command is a newly created tsconfig.json file that is packed with a lot of default options to configure our TypeScript project compiler – most of them are not enabled by default. The configuration options are accompanied by comments that explain what each one configures in our compiler!
{
"compilerOptions": {
/* Basic Options */
"target":
"es5" /* Specify ECMAScript target version: ‘ES3’ (default), ‘ES5’, ‘ES2015’, ‘ES2016’, ‘ES2017’, or ‘ESNEXT’. */,
"module":
"commonjs" /* Specify module code generation: ‘none’, commonjs’, ‘amd’, ‘system’, ‘umd’, ‘es2015’, or ‘ESNext’. */,
// "lib": [], /* Specify library files to be included in the compilation: */
// "allowJs": true, /* Allow javascript files to be compiled. */
// "checkJs": true, /* Report errors in .js files. */
// "jsx": "preserve", /* Specify JSX code generation: ‘preserve’, ‘react-native’, or ‘react’. */
// "declaration": true, /* Generates corresponding ‘.d.ts’ file. */
// "sourceMap": true, /* Generates corresponding ‘.map’ file. */
// "outFile": "./", /* Concatenate and emit output to single file. */
// "outDir": "./", /* Redirect output structure to the directory. */
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with –outDir. */
// "removeComments": true, /* Do not emit comments to output. */
// "noEmit": true, /* Do not emit outputs. */
// "importHelpers": true, /* Import emit helpers from ‘tslib’. */
// "downlevelIteration": true, /* Provide full support for iterables in ‘for-of’, spread, and destructuring when targeting ‘ES5’ or ‘ES3’. */
// "isolatedModules": true, /* Transpile each file as a separate module (similar to ‘ts.transpileModule’). */
/* Strict Type-Checking Options */
"strict": true /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied ‘any’ type. */
// "strictNullChecks": true, /* Enable strict null checks. */
// "noImplicitThis": true, /* Raise error on ‘this’ expressions with an implied ‘any’ type. */
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
/* Additional Checks */
// "noUnusedLocals": true, /* Report errors on unused locals. */
// "noUnusedParameters": true, /* Report errors on unused parameters. */
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
/* Module Resolution Options */
// "moduleResolution": "node", /* Specify module resolution strategy: ‘node’ (Node.js) or ‘classic’ (TypeScript pre-1.6). */
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the ‘baseUrl’. */
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
// "typeRoots": [], /* List of folders to include type definitions from. */
// "types": [], /* Type declaration files to be included in compilation. */
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
/* Source Map Options */
// "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
// "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires ‘–inlineSourceMap’ or ‘–sourceMap’ to be set. */
/* Experimental Options */
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
}
}

The best part of this new tsconfig.json is definitely how well documented the options are – they are pretty self-explanatory! You don’t have to use all of these options though. For most of my Angular applications that use TypeScript, I use the following configuration:
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"outDir": "dist",
"sourceMap": true,
"experimentalDecorators": true
},
"files": [
"./node_modules/@types/mocha/index.d.ts",
"./node_modules/@types/node/index.d.ts"
],
"include": ["src/**/*.ts"],
"exclude": ["node_modules"]
}

Note that es6 and ES2015 can be used interchangeably.

I added three additional properties to tsconfig.json (files, include and exclude) that allow us to specify which files in the containing directory and subdirectories should be compiled:

When files or include properties are specified, the compiler will only process a union of the files listed as the value of these properties.
files takes a list of relative or absolute file paths, whereas include and exclude take a list of glob-like file patterns.
exclude is used to filter the files listed under include; however, any files that have been explicitly listed under files are always included regardless of them matching any pattern defined under exclude.

I presented my tsconfig.json as an example to showcase the file filtering capabilities of the compiler. Running tsc with it in our ts-intro folder will give us an error saying that the paths specified in files are not found. Again, I use this for my Angular projects that makes use of node_modules – if you wish, give it a try on your projects.
We’ve covered a lot so far. We’ve learned how to create a TypeScript file, how to compile a TypeScript file, and how to configure the compiler to render different compilations of a TypeScript file. There’s much, much more that can be configured through tsconfig.json but that’s a story for another post!
TypeScript Playground
Whenever you need to perform some quick experimentation with how TypeScript code would compile to JavaScript it’s not necessary to go through all this setup. The TypeScript Team created an online tool that allows us to compile TypeScript code and compare it side by side with its JavaScript output online. This tool is called TypeScript Playground and we can access it at typescriptlang.org/play.
TypeScript Playground allows you to share the code snippets you create there with others. You can access the Playground for barista.ts here.
The Playground also has built-in examples that showcase TypeScript code snippets of different complexities and categories, such as using generics. Use it at your leisure to create deep mapping knowledge between TypeScript and JavaScript easily.
Conclusion
TypeScript brings a lot of benefits to our productivity and developer experience. We’ve seen that integrating it with an existing JavaScript project is easy and carries little to no overhead. TypeScript is not unique to Angular, other powerful frontend frameworks such as React and Vue are starting to be used with TypeScript to allow developer teams to create applications that are reliable, sustainable and scalable. JavaScript and TypeScript are continually evolving but not competing against each other. TypeScript was created to complement and enhance JavaScript – not replace it. The future may see them becoming very similar in features but with TypeScript remaining the statically typed alternative.
With this TypeScript introduction, we’ve just scratched the surface of all the amazing things that we can do with TypeScript. I hope you enjoyed this post!
If you’re interested in taking your TypeScript skills to an ultimate level, I invite you to come and learn TypeScript basic and advanced concepts with me at Ultimate Angular – don’t worry if you are not an Angular developer, the course is designed completely around TypeScript!

Link: https://toddmotto.com/typescript-introduction

Angular Developer: JavaScript to TypeScript

New JavaScript frameworks and libraries are created every day. This generates a dilemma: which solution should we use when starting a project?
My web development experience over the last few years has mainly included the AngularJS and Backbone.js frameworks. Angular, jQuery, and traditional JavaScript have been in my comfort zone. When I ended up coming face-to-face with TypeScript, it felt new, scary, and pretty confusing. I want to make that transition easier for you!

Link: https://dzone.com/articles/angular-developer-javascript-to-typescript?utm_medium=feed&utm_source=feedpress.me&utm_campaign=Feed%3A+dzone%2Fwebdev

5 Angular Directives You Can Use in Your Project

In a recent post, we showed off some examples of Angular pipes we use in our code base. Now, we’d like to talk about directives. Angular directives allow you to attach behavior to elements in the DOM and reuse it across your project. The framework already comes with a number of convenient directives like NgStyle, NgIf, NgFor, and NgSwitch.
We’ve written over 65 custom directives so far and would like to share the top five that we think you’ll find useful in your project. Just note that the directives in the demos below were intentionally distilled to the bare minimum for clarity and don’t have extensive customization options or destructors/cleanup code. Use them as a starting point.

Link: https://dzone.com/articles/5-angular-directives-you-can-use-in-your-project?utm_medium=feed&utm_source=feedpress.me&utm_campaign=Feed%3A+dzone%2Fwebdev

How an Angular Project Is Built

Yesterday I introduced the foundations of Angular and today I’m going to briefly explain how an Angular project is built and why adding an Angular component to an ASP.NET Core is not as easy as just adding a few JavaScript files in a folder. The following is an extract from chapter 3 of my upcoming book “Front-end Development with ASP.NET Core, Angular, and Bootstrap."

Link: https://dzone.com/articles/how-an-angular-project-is-built?utm_medium=feed&utm_source=feedpress.me&utm_campaign=Feed%3A+dzone%2Fwebdev

Classes vs Interfaces in TypeScript

Classes and interfaces are powerful structures that facilitate not just object-oriented programming but also type-checking in TypeScript. A class is a blueprint from which we can create objects that share the same configuration – properties and methods. An interface is a group of related properties and methods that describe an object, but neither provides implementation nor initialisation for them.
Since both of these structures define what an object looks like, both can be used in TypeScript to type our variables. The decision to use a class or an interface truly depends on our use case: type-checking only, implementation details (typically via creating a new instance), or even both! We can use classes for type-checking and the underlying implementation – whereas we cannot with an interface. Understanding what we can get from each structure will easily let us make the best decision that will enhance our code and improve our developer experience.

Table of contents

Using TypeScript class
Using TypeScript interface
Using TypeScript class vs using Typescript interface

Conclusion

Using TypeScript class
ES6 introduced class officially to the JavaScript ecosystem. TypeScript boosts JavaScript classes with extra power such as type-checking and static properties. This also means that whenever we transpile our code to whatever target JavaScript of our choice, the transpiler will keep all of our class code present in the transpiled file. Hence, classes are present throughout all the phases of our code.
We use classes as object factories. A class defines a blueprint of what an object should look like and act like and then implements that blueprint by initialising class properties and defining methods. Therefore, when we create an instance of the class, we get an object that has actionable functions and defined properties. Let’s look at an example of defining a class named PizzaMaker:
class PizzaMaker {
static create(event: { name: string, toppings: string[] }) {
return { name: event.name, toppings: event.toppings };
}
}

PizzaMaker is a simple class. It has a static method called create. What makes this method special is that we can use it without creating an instance of the class. We just invoke the method on the class directly – much like we would with something like Array.from:
const pizza = PizzaMaker.create({ name: ‘Inferno’, toppings: [‘cheese’, ‘peppers’] });

console.log(pizza);
// Output: { name: ‘Inferno’, toppings: [ ‘cheese’, ‘peppers’ ] }

Then, PizzaMaker.create() returns a new object – not a class – with a name and toppings properties defined from the object passed to it as argument.
If PizzaMaker did not define create as a static method, then to use the method we would need to create an instance of PizzaMaker:
class PizzaMaker {
create(event: { name: string, toppings: string[] }) {
return { name: event.name, toppings: event.toppings };
}
}

const pizzaMaker = new PizzaMaker();

const pizza = pizzaMaker.create({ name: ‘Inferno’, toppings: [‘cheese’, ‘peppers’] });

console.log(pizza);
// Output: { name: ‘Inferno’, toppings: [ ‘cheese’, ‘peppers’ ] }

We get the same output we had with create as a static method. Being able to use TypeScript classes with and without an existing instance of a class makes them extremely versatile and flexible. Adding static properties and methods to a class makes them act like a singleton while defining non-static properties and methods make them act like a factory.
Now, unique to TypeScript is the ability to use classes for type-checking. Let’s declare a class that defines what a Pizza looks like:
class Pizza {
constructor(public name: string, public toppings: string[]) {};
}

In the Pizza class definition, we are using a handy TypeScript shorthand to define class properties from the arguments of the constructor – it saves a lot of typing! Pizza can create objects that have a name and a toppings property:
const pizza = new Pizza(‘Inferno’, [‘cheese’, ‘peppers’]);

console.log(pizza);
// Output: Pizza { name: ‘Inferno’, toppings: [ ‘cheese’, ‘peppers’ ] }

Aside from the Pizza name before the pizza object that shows that the object is in fact an instance of the Pizza class, the output of new Pizza(…) and PizzaMaker.create(…) is the same. Both approaches yield an object with the same structure. Therefore, we can use the Pizza class to type-check the event argument of PizzaMaker.create(…):
class Pizza {
constructor(public name: string, public toppings: string[]) {};
}

class PizzaMaker {
static create(event: Pizza) {
return { name: event.name, toppings: event.toppings };
}
}

We’ve made PizzaMaker much more declarative, and hence, much more readable. Not only that, but if we need to enforce the same object structure defined in Pizza in other places, we now have a portable construct to do so! Append export to the definition of Pizza and you get access to it from anywhere in your application.
Using Pizza as a class is great if we want to define and create a Pizza, but what if we only want to define the structure of a Pizza but we’d never need to instantiate it? That’s when interface comes handy!
Using TypeScript interface
Unlike classes, an interface is a virtual structure that only exists within the context of TypeScript. The TypeScript compiler uses interfaces solely for type-checking purposes. Once your code is transpiled to its target language, it will be stripped from its interfaces – JavaScript isn’t typed, there’s no use for them there.
And, while a class may define a factory or a singleton by providing initialisation to its properties and implementation to its methods, an interface is simply a structural contract that defines what the properties of an object should have as a name and as a type. How you implement or initialise the properties declared within the interface is not relevant to it. Let’s see an example by transforming our Pizza class into a Pizza interface:
interface Pizza {
name: string;
toppings: string[];
}

class PizzaMaker {
static create(event: Pizza) {
return { name: event.name, toppings: event.toppings };
}
}

Since Pizza as a class or as interface is being used by the PizzaMaker class purely for type-checking, refactoring Pizza as an interface did not affect the body of the PizzaMaker class at all. Observe how the Pizza interface just lists the name and toppings properties and gives them a type. What also changed is that we cannot create an instance of Pizza anymore. Let’s further explain this core difference between interface and class by considering Pizza as a class again.
Using TypeScript class vs using Typescript interface
As it is, our current code provides type-checking for Pizza but can’t create a pizza:
interface Pizza {
name: string;
toppings: string[];
}

class PizzaMaker {
static create(event: Pizza) {
return { name: event.name, toppings: event.toppings };
}
}

This is unfortunate because we are missing a golden opportunity to further improve the declarative nature and readability of our code. Notice how PizzaMaker.create() returns an object that surely looks a lot like a Pizza would! It has a name that is a string and it has toppings that is a string array – we infer the property types from the type of event which is Pizza. Wouldn’t it be awesome if we could return an instance of Pizza from within PizzaMaker.create()?
As mentioned many times earlier, we can’t instantiate the Pizza interface, doing so will trigger an error. However, we can refactor again Pizza to be a class and then return an instance of Pizza:
class Pizza {
constructor(public name: string, public toppings: string[]) {};
}

class PizzaMaker {
static create(event: Pizza) {
return new Pizza(event.name, event.toppings);
}
}

const pizza = PizzaMaker.create({ name: ‘Inferno’, toppings: [‘cheese’, ‘peppers’] };

We enforce the structure that the event argument of PizzaMaker.create() takes whilst still being able to create the object that the type Pizza as a class defines! We get the best of both worlds here – the blueprint and the contract. It’s up to you which one you need for your use cases.
Conclusion
We’ve learned a lot, without really diving into a huge amount of code. The tl:dr; is if you need/wish to create an instance of perhaps a custom object, whilst getting the benefits of type-checking things such as arguments, return types or generics – a class makes sense. If you’re not creating instances – we have interfaces at our disposal, and their benefit comes from not generating any source code, yet allowing us to somewhat “virtually” type-check our code.
Since both an interface and a class define the structure of an object and can be used interchangeably in some cases, it’s worth noting that if we need to share structural definition amongst various classes, we can define that structure in an interface and then have each class implement that interface! Each class then will have to declare or implement each property of the interface. That’s the power of TypeScript, and it’s also super flexible. We have comprehensive object-oriented design paired with versatile type-checking.

Link: https://toddmotto.com/classes-vs-interfaces-in-typescript

Finally understand Redux by building your own Store

Redux is an interesting pattern, and at its core a very simple one – but why does it feel complex to understand? In this post, we’re going to dive into Redux by assembling our own custom Store, written in TypeScript.

Table of contents

Terminology
Actions
Reducers
Store

Store API
Store.dispatch()
Store.subscribe()
Store.value

Store Container
Our state data structure
Updating our state tree

Writing Reducer functionality
Creating a Reducer
Registering a Reducer
Invoking Reducers in the Store
Reducing initialState

Enabling subscribers
Store Subscribers
Unsubscribing from the Store

Final Code
Wrapping up

This post is based off my “vanilla TypeScript Redux store”, you can grab the source code and follow along here if you wish. Please bear in mind, this is for learning purposes to understand the mechanics inside a Store – following the Redux pattern.

Terminology
If you’re new to Redux, or have flicked through the documentation, you’ll have likely come across a few of the following terms, which I think is worth covering before we begin.
Actions
Don’t try and think about actions as a JavaScript API, actions have a purpose – and we need to understand that first. Actions inform the Store of our intent.

You’re essentially passing an instruction, such as “Hey Store! I’ve got an instruction for you, please update the state tree with this new piece of information.”

The signature of an action, using TypeScript to demonstrate, is as follows:
interface Action {
type: string;
payload?: any;
}

Payload is an optional property, as sometimes we may dispatch some kind of “load” action which accepts no payload, though most of the time we’ll use the payload property.
This means that we’ll create something like this:
const action: Action = {
type: ‘ADD_TODO’,
payload: { label: ‘Eat pizza,’, complete: false },
};

That’s pretty much the blueprint of an action. Let’s continue!
Reducers
A reducer is simply a pure function which accepts the state of our application (our internal state tree, which our Store passes to the reducer), and finally a second argument of the action which was dispatched. Which means we end up with something like this:
function reducer(state, action) {
//… that was easy
}

Okay, so what’s next to understand a reducer? The reducer gets passed our state as we know, and to do something useful (such as updating our state tree), we need to respond to the action’s type property (which we just looked at above). This is typically done via a switch:
function reducer(state, action) {
switch (action.type) {
case ‘ADD_TODO’: {
// I guess we should do something now…
}
}
}

Each case inside the switch allows us to respond to the different types of actions that compose state in our applications. For instance, let’s say we want to add a property with a value to our state tree, we’d simply return it:
function reducer(state = {}, action) {
switch (action.type) {
case ‘ADD_TODO’: {
return {
…state,
// we spread the existing todos array into a new array
// and then add our new todo on the end
todos: […state.todos, { label: ‘Eat pizza,’, complete: false }],
};
}
}

return state;
}

Note at the bottom here, we’re returning state to pass the state back if we do not match a particular action. You’ll notice that I’ve added state = {} in the first argument (which is supplying a default value for the parameter). These initial state objects are typically abstracted above the reducer, and we’ll look at this as we continue.
The final thing to note here, is our push for immutability. We’re returning a brand new object in each case, which reflects the new state tree changes, as well as the existing state tree representation – which means we have a slightly modified state object. The way we merge existing state is via the …state, where we simply spread the current state in, and add additional properties after.

To honour the concept of pure functions, given the same input we return the same output each time. Reducers handle purely dynamic state and actions, in short we set them up – and they handle the rest. They’re encapsulated functions that simply contain the pieces of logic necessary to update our state tree, based on which type of instruction we are sending (via an action).

Reducers are purely synchronous, we should avoid asynchronous intent inside a reducer.
So where does the action.payload come into play? Ideally we wouldn’t hard-core values into a reducer, unless they were simple things like a boolean toggle from false to true. To complete our full circle trip of abiding by the “pure functions” rule, we access the action.payload property supplied in the function arguments to obtain any data we’ve dispatched via an action:
function reducer(state = {}, action) {
switch (action.type) {
case ‘ADD_TODO’: {
// give me new data
const todo = action.payload;
// compose new data structure
const todos = […state.todos, todo];
// return new state representation
return {
…state,
todos,
};
}
}

return state;
}

Store
One thing I see is confusion between “state” and “store”. Store is your container, state lives in the container. Store is an object with an API that lets you interact with your state, by modifying it, asking for its value – and so forth.
I think we’re about ready to begin building our custom Store, and all of these separate topics will start to click into place as we continue.

One thing I like to tell others is “this is just a structured process for updating a property on an object”. That is Redux.

Store API
Our example Redux Store is going to have just a few public properties and methods. We’ll then use our Store as follows, supplying any reducers and initial state for our application:
const store = new Store(reducers, initialState);

Store.dispatch()
The dispatch method will allow us to present an instruction to our Store, informing it that we intend to change the state tree. This is handled via our reducer, which we’ve just covered.
Store.subscribe()
The subscribe method will allow us to pass a subscriber function into our Store, which when our state tree changes, we can pass that new state tree changes down via an argument to our .subscribe() callback.
Store.value
The value property will be setup as a getter and return the internal state tree (so we can access properties).
Store Container
As we know, the Store contains our state, and also allows us to dispatch actions and subscribe to new state tree updates. So let’s start with our Store class:
export class Store {
constructor() {}

dispatch() {}

subscribe() {}
}

This looks good for now, but we’re missing our “state” object. Let’s get it added:
export class Store {
private state: { [key: string]: any };

constructor() {
this.state = {};
}

get value() {
return this.state;
}

dispatch() {}

subscribe() {}
}

I’m using TypeScript here, as I much prefer it, to define that our state object will be composed of keys of type string, with any value. Because that’s exactly what we need for our data structures.
We’ve also added the get value() {} which internally returns the state object, when accessed as a property, i.e. console.log(store.value);.
So now we’ve got this, let’s instantiate it:
const store = new Store();

Voila.
At this point we could actually call a dispatch if we wanted:
store.dispatch({
type: ‘ADD_TODO’,
payload: { label: ‘Eat pizza’, complete: false },
});

But it’s not going to do anything, so let’s dive into focusing on our dispatch and supplying that action:
export class Store {
// …
dispatch(action) {
// Update state tree here!
}
// …
}

Okay, so inside the dispatch, we need to update our state tree. But first – what does our state tree even look like?
Our state data structure
For this article, our data structure will look like this:
{
todos: {
data: [],
loaded: false,
loading: false,
}
}

Why? We’ve learned so far that reducers update our state tree. In a real app, we’ll have many reducers, which are responsible for updating specific parts of the state tree – which we often refer to as “slices” of state. Each slice is managed by a reducer.
In this case, our todos property on our state tree – the todos slice – is going to be managed by a reducer. Which at this point, our reducer will simply manage the data, loaded and loading properties of this slice. We’re using loaded and loading because when we perform asynchronous tasks such as fetching JSON over HTTP, we want to remain in control of the various steps it takes from initiating the request – to the request being fulfilled.
So, let’s jump back into our dispatch method.
Updating our state tree
In order to follow immutable update patterns, we should assign a new representation of state to our state property as a brand new object. This new object consists of any changes we’re intending to make to the state tree, via an action.
For this example, let’s ignore the fact that reducers even exist and simply update the state manually:
export class Store {
// …
dispatch(action) {
this.state = {
todos: {
data: […this.state.todos.data, action.payload],
loaded: true,
loading: false,
},
};
}
// …
}

After we’ve dispatched this ‘ADD_TODO’ action, our state tree now looks like this:
{
todos: {
data: [{ label: ‘Eat pizza’, complete: false }],
loaded: false,
loading: false,
}
}

Writing Reducer functionality
Now we’ve got an understanding that a reducer updates a slice of state, let’s start by defining that initial slice:
export const initialState = {
data: [],
loaded: false,
loading: false,
};

Creating a Reducer
Next up, we need to supply our reducer function that state argument, with a default value of the above initialState object. This sets up the reducer for initial load, when we invoke the reducer in the Store to bind all initial state, inside all of the reducers:
export function todosReducer(
state = initialState,
action: { type: string, payload: any }
) {
// don’t forget to return me
return state;
}

We should probably be able to guess the rest of the reducer at this point:
export function todosReducer(
state = initialState,
action: { type: string, payload: any }
) {
switch (action.type) {
case ‘ADD_TODO’: {
const todo = action.payload;
const data = […state.data, todo];
return {
…state,
data,
};
}
}

return state;
}

Okay, so this is great so far – but the reducer needs hooking up to the Store so we can invoke it to pass the state and any actions.
Back inside the Store, we should have this so far:
export class Store {
private state: { [key: string]: any };

constructor() {
this.state = {};
}

get value() {
return this.state;
}

dispatch(action) {
this.state = {
todos: {
data: […this.state.todos.data, action.payload],
loaded: true,
loading: false,
},
};
}
}

We now need to hook in the ability to add reducers to the Store:
export class Store {
private state: { [key: string]: any };
private reducers: { [key: string]: Function };

constructor(reducers = {}, initialState = {}) {
this.reducers = reducers;
this.state = {};
}

}

We’re also supplying any initialState to the Store, so we can supply this when we invoke the Store should we wish to.
Registering a Reducer
To register a reducer, we must remember that todos property on our expected state tree – and bind our reducer function to it. Remember, we’re managing a slice of state called “todos”:
const reducers = {
todos: todosReducer,
};

const store = new Store(reducers);

This is the magic piece where the property todos is then the result of the Store invoking the todosReducer – which as we know returns new state based on a particular action.
Invoking Reducers in the Store
The reason reducers are called “reducers” is because they reduce new state. Think Array.prototype.reduce, where we end up with one final value. In our case, this final value is the new representation of state. Sounds like we need a loop.
What we’re going to do is wrap our “reducing” logic in a function, which here I’ve called reduce:
export class Store {
// …
dispatch(action) {
this.state = this.reduce(this.state, action);
}

private reduce(state, action) {
// calculate and return new state
return {};
}
}

When we dispatch an action, we’ll in fact call the reduce method we’ve created on the Store class – and pass the state and action inside. This is actually called the root reducer. You’ll notice it takes the state and action – much like our todosReducer also does.
So, let’s dive into our private reduce method, because this is the most important step for the composition of our state tree to fully click.
export class Store {
private state: { [key: string]: any };
private reducers: { [key: string]: Function };

constructor(reducers = {}, initialState = {}) {
this.reducers = reducers;
this.state = {};
}

dispatch(action) {
this.state = this.reduce(this.state, action);
}

private reduce(state, action) {
const newState = {};
for (const prop in this.reducers) {
newState[prop] = this.reducers[prop](state[prop], action);
}
return newState;
}
}

What’s happening here is:

We create a newState object which will contain the new state tree
We iterate this.reducers, which we register in the Store
We map across each property on our reducer, i.e. todos, to the newState
We invoke each reducer, one at a time, and invoke it – passing in the slice of state (via state[prop]) and the action

The prop value in this case, is just todos, so you can think of it like this:
newState.todos = this.reducers.todos(state.todos, action);

Reducing initialState
There’s one final piece, our initialState object. If you want to use the Store(reducers, initialState) syntax to provide store-wide initial state, we need to reduce it as well upon Store creation:
export class Store {
private state: { [key: string]: any };
private reducers: { [key: string]: Function };

constructor(reducers = {}, initialState = {}) {
this.reducers = reducers;
this.state = this.reduce(initialState, {});
}

// …
}

Remember when we talked about return state at the bottom of each reducer? Now you know why! We have this option to pass {} as the action, meaning the switch cases will be avoided – and we end up with a state tree we supply through the constructor.
Enabling subscribers
You’ll often hear the term “subscribers” in the Observable world, where each time an Observable emits a new value, we are notified via a subscription. A subscription is simply “give me data when it’s available, or changes”.
In our case, this would be handled like so:
const store = new Store(reducers);

store.subscribe(state => {
// do something with `state`
});

Store Subscribers
Let’s add a few more properties to our Store to allow us to setup this subscription:
export class Store {
private subscribers: Function[];

constructor(reducers = {}, initialState = {}) {
this.subscribers = [];
// …
}

subscribe(fn) {}

// …
}

Here we have our subscribe method, which now accepts a function (fn) as the argument. What we need to do is pass each function into our subscribers array:
export class Store {
// …

subscribe(fn) {
this.subscribers = […this.subscribers, fn];
}

// …
}

That was easy! So where does it make sense to inform our subscribers that something changed? In the dispatch of course!
export class Store {
// …

get value() {
return this.state;
}

dispatch(action) {
this.state = this.reduce(this.state, action);
this.subscribers.forEach(fn => fn(this.value));
}

// …
}

Again, super easy. Any time we dispatch, we reduce the state and loop our subscribers – and pass in this.value (remember that’s our value getter).
Buuuuuuut, there’s just one more thing. When we call .subscribe() we won’t (at this point in time) get the state value right away. We’ll only get it after we dispatch. Let’s make a concious decision to inform new subscribers of the current state, as soon as they subscribe:
export class Store {
// …

subscribe(fn) {
this.subscribers = […this.subscribers, fn];
fn(this.value);
}

// …
}

That was also nice and easy – we get given fn – the function – via the subscribe method, and we can just simply invoke that function as soon as we subscribe, and pass the value of the state tree in.
Unsubscribing from the Store
When we subscribe, we always want to be able to unsubscribe – for purposes such as avoiding memory leaks, or simply because we don’t care about the data anymore.
All we need to do is return a function closure, which when invoked will unsubscribe us (by removing the function from our list of subscribers):
export class Store {
// …

subscribe(fn) {
this.subscribers = […this.subscribers, fn];
fn(this.value);
return () => {
this.subscribers = this.subscribers.filter(sub => sub !== fn);
};
}

// …
}

We simply use the function’s reference, iterate our subscribers, check if the current subscriber does not equal our fn, and by using Array.prototype.filter, it magically is removed from our subscribers array.
And we can use it as follows:
const store = new Store(reducers);

const unsubscribe = store.subscribe(state => {});

destroyButton.on(‘click’, unsubscribe, false);

And that’s all we need.
The beauty of subscriptions is we can also have multiple subscribers, meaning different parts of our application are interested in different slices of state.
Final Code
Here’s the full picture and finished solution:
export class Store {
private subscribers: Function[];
private reducers: { [key: string]: Function };
private state: { [key: string]: any };

constructor(reducers = {}, initialState = {}) {
this.subscribers = [];
this.reducers = reducers;
this.state = this.reduce(initialState, {});
}

get value() {
return this.state;
}

subscribe(fn) {
this.subscribers = […this.subscribers, fn];
fn(this.value);
return () => {
this.subscribers = this.subscribers.filter(sub => sub !== fn);
};
}

dispatch(action) {
this.state = this.reduce(this.state, action);
this.subscribers.forEach(fn => fn(this.value));
}

private reduce(state, action) {
const newState = {};
for (const prop in this.reducers) {
newState[prop] = this.reducers[prop](state[prop], action);
}
return newState;
}
}

You can see that in reality, there isn’t much going on here.
Wrapping up
That wasn’t so bad was it? We’ve likely used/seen/heard about all these different terminology examples, but haven’t necessarily dived underneath to think about how they are composed.
We’ve finally understood what a Store does for us, by creating our own. It’s taking the magic away from simply creating an action, reducer, and just letting it “work”. We fully grasped the concepts and mechanics of what’s happening; our dispatch tells the Store to carry out a process of defining new state by invoking each reducer and attempting to match our action.type with a switch case. Our state tree is simply a final representation of having invoked all of our reducers.
For me, this was the biggest part in understanding Redux, and I hope it’s helped you on your way too!
You can take this one step further with my NGRX course for Angular, which is free for everyone, to learn how to master state management with NGRX Store and Effects.

Link: https://toddmotto.com/redux-typescript-store

Converting 600k Lines to TypeScript in 72 Hours

Background
Users have been using Lucidchart for a long time to make their diagrams, since 2010 and IE6. And for nearly that long, Lucid has used Google’s Closure Compiler to manage its increasingly sophisticated code base. Closure Compiler is a typechecker and minifier that uses JSDoc annotations in comments to understand type information. As Lucid grew from 5 to 15 to 50 engineers, the tool proved enormously helpful for quality and productivity.Then in 2016, Lucid began experimenting with TypeScript. TypeScript offers more flexible and comprehensive type checking, cleaner syntax, and better IDE support than we could get with Closure-annotated JavaScript.
// Closure JavaScript

/** @const {!goog.events.EventId} */
lucid.model.DocumentEvents.PAGES_CONTENT_CHANGED =
new goog.events.EventId(goog.events.getUniqueId(‘PAGES_CONTENT_CHANGED’));

/**
* @constructor
* @extends {goog.events.Event}
* @final
* @param {!Object<boolean>} pages
* @struct
*/
lucid.model.DocumentEvents.PagesContentChanged = function(pages) {
lucid.model.DocumentEvents.PagesContentChanged.base(
this, ‘constructor’, lucid.model.DocumentEvents.PAGES_CONTENT_CHANGED
);
/** @const {!Object<boolean>} */
this.pages = pages;
};
goog.inherits(lucid.model.DocumentEvents.PagesContentChanged, goog.events.Event);
is equivalent to

Link: https://dzone.com/articles/converting-600k-lines-to-typescript-in-72-hours?utm_medium=feed&utm_source=feedpress.me&utm_campaign=Feed%3A+dzone%2Fwebdev

An Introduction to Node.js

Introduction
Node.js is an application framework and sometimes is referred to as a runtime, through which applications are built using the JavaScript programming language. Node.js is well known for its speed, due to the fact that it is non-blocking. Further, being non-blocking means one request does not wait for the other request to finish (i.e it is asynchronous). The asynchronicity is what makes Node.js the framework that it is today in terms of throughput, unlike Java application servers which are mostly blocking each request that is bound to a thread and as soon as there are no more threads available the server almost always stops receiving requests.
In this article, we will discover some aspects of Node.js. We will do so by discussing some topics such as: uses cases of Node.js, how Node.js achieves concurrency, and its main design pattern.  

Link: https://dzone.com/articles/an-introduction-to-nodejs?utm_medium=feed&utm_source=feedpress.me&utm_campaign=Feed%3A+dzone%2Fwebdev