Practical guides, tutorials, and insights from years of building web and desktop applications. Check out code examples you can actually use!
Here’s a shorter, readable way to copy props from one object to another subject to defined conditions.
The shortest way to copy object (when you don’t quite care about copying sub objects by reference) -
const planet = { name: "earth", position: 3 }; const newPlanet = { ...planet }; console.log(newPlanet); // { name: 'earth', position: 3 } But, what do you do if you want to copy only name but not position?
A common way to do that will be -
const planet = { name: "earth", position: 3 }; const newPlanet = {}; Object.keys(planet).forEach(key => { key == "position" ? "" : (newPlanet[key] = key); }); console.log(newPlanet); // { name: 'name' } Not bad - the code is readable and we have accomplished the task in two lines.
...
There are situations when you need to initialize object without props. How do you manage that it Typescript?
Let’s consider the example below. First, we declare the object and initialize it to an empty object.
const planet = {}; Then, we add the props -
planet.name = "earth"; The above initialization + assignment combination is perfectly valid in Javascript.
But Typescript does not agree with planet.name since the object was declared as type {} (an empty object).
...
A simpler way to do curry functions in Javascript.
We have previously seen currying in Javascript. A simple form and application of that concept is demonstrated below -
const addThem = add.curry(2); const addTotal = addThem(1); console.log("addTotal: ", addTotal); // 3 Or, we could avoid a external function or library and curry using bindings ..
function add(x) { return function(y) { return y + x; }; } const addEm = add(1); console.log(addEm(2)); // 3 But, there is a simpler way to get the same result.
We just use arrow functions to collect arguments at different times.
...
Typescript provides a way to indicate props in an object / type, or an entire type, as read only.
Props in an object Consider this example -
class Fruit { readonly name = "apple"; color = "red"; } In the code block we have specified the prop name as read-only.
We can very much change the color of an object derived from Fruit.
const apple = new Fruit(); console.log(apple); // Fruit { name: 'apple', color: 'red' } apple.color = "blue"; console.log(apple); // Fruit { name: 'apple', color: 'blue' } But, we cannot change the name -
...
Typeguards enable us to process function arguments based on their types.
Consider this example -
function join(a: string): string { return a; } console.log(join("hello")); // hello What if we want to use join for strings or numbers? We can do a union type like so -
function join(a: string | number): string | number { return a; } console.log(join("hello")); // hello console.log(join(1)); // 1 But, a real world problem would lie in processing the input arguments - not just returning them. Also, the methods and properties of the argument will change within a function based on their types. Typescript solves this problem using Typeguard.
...
Typescript provides a convenient way to accept different types of arguments for a function, or to combine multiple types into one super type.
Consider this example -
function printThis(a: string) { return typeof a; } console.log(printThis("hello")); // string This function is fine if we want to return the input string for some strange reason. But, what if we want to generalise that function to - say, numbers?
Union type In Typescript we can simply specify the argument as being string or a number using what is called “union type”.
...
Overload functions to change signatures and provide optional arguments in Typescript.
We have previously seen an option to provide optional arguments to a function in Typescript. But, there is more to that to function overloads.
Building on our previous example -
function getSum(i: number, j?: number, k?: number): number { j = j || 0; k = k || 0; return i + j + k; } console.log(getSum(1)); // 1 In the example, we have simply made j and k optional arguments and made their value 0 if they are not provided. Although this is evident for someone who looks at the function definition, it is not so for a person looking at the declaration or the auto-complete when initializing this function.
...
Let us discuss everyone’s favourite topic since Typescript was invented - ‘duck typing’.
Duck typing is type safety checks for complex types. It gets its name following the adage -
If it walks like a duck and quacks like a duck, it must be a duck.
Typescript modifies it slightly to -
Don’t check whether it is a duck. If it quacks like a duck.. etc., it must be a duck
Consider an example with a couple of variables of type objects and derived from a class.
...
Allow additional arguments or optional arguments for function calls in Typescript.
Consider the below example of a function that adds two numbers.
function getSum(i: number, j: number): number { return i + j; } console.log(getSum(1, 2)); // 3 This works fine and as expected, but what happens when there is a discrepancy in number of arguments.
function getSum(i: number, j: number): number { return i + j; } console.log(getSum(1)); // error TS2554: Expected 2 arguments, but got 1. // An argument for 'j' was not provided. The above error is perfect.
...
Beware of using implicit returns in arrow functions.
Consider the below example of a simple arrow function. It returns a simple variable. In the absence of any other statement in the function body, a simple mention of x will return the value of x.
const getStuff = x => x; console.log(getStuff(1)); // 1 Let’s modify the block. We now want to return an object with the input value within it.
const getMoreStuff = x => { x: x; }; console.log(getStuff(1)); // 1 Oops.. We expected {x: 1} but got 1 because the flower brackets were treated as enclosing a function body and not an object.
...