TypeScript is an easy to learn extension of JavaScript. It’s easy to write programs that run and does something. However, it’s hard to account for all the uses cases and write robust TypeScript code.
In this article, we’ll look at the best practices to following when writing code with TypeScript, including better ways to check the start and end of strings.
Also, we look why we should check all the types of a union type and make sure that both operands are of the same type before using the +
operator.
Use startsWith and endsWith Instead of Other Equivalent Methods to Check Substrings
If we’re checking whether a string starts with or ends with some substring, then we should use the startsWith
or endsWith
methods to search for substrings.
For instance, instead of using:
foo.indexOf('bar') === 0;
or:
foo.substring(0, 3) === 'bar';
We can write:
foo.startsWith('bar');
Likewise, if we want if a string ends with something, instead of writing:
foo.slice(-3) === 'bar';
or:
foo.substring(foo.length - 3) === 'bar';
We can write:
foo.endsWith('bar');
It saves us lots of headaches with dealing with string indexes.
Use //@ts-expect-error over //@ts-ignore
//@ts-ignore
suppresses all TypeScript errors before the erroring line.
If we use //@ts-expect-error
, which is available since TypeScript 3.9, we can tell people that the error they encounter is expected instead of suppressing all errors.
Use any Function or a Method that Returns a Promise to be Marked async
The async-await syntax is a shorter way to write a function that returns a promise.
Therefore, we should use it as much as possible.
For instance, instead of writing:
const foo = () => Promise.resolve('foo');
We write:
const foo = async () => Promise.resolve('value');
Require array.sort Calls to Always Provide a Compare Function
By default, the sort
method that’s part of an array instance sorts everything as if they’re strings.
Therefore, we should provide a comparator function so that we can compare our array entries properly.
For instance, if we want to sort numbers in ascending order, instead of writing:
const arr = [2, 3, 1];
arr.sort();
We write:
const arr = [2, 3, 1];
arr.sort((a, b) => a - b);
When Adding 2 Variables, Operands Must Both be of Type Number or String
The +
operator is both used for addition or concatenation.
Therefore, we should make sure that we’re doing what we want by making both operands the same type.
Otherwise, we may get unexpected results.
For instance, instead of writing:
const foo = 1 + '1';
which will concatenate the operands, we should write:
const foo = 1 + Number('1');
so that they’re both numbers and we can add them together.
Use Template Expressions for Strings
Template strings are much better than regular strings. We can put expressions in them and we can make multiline expressions without hassle.
So we should use them as much as possible.
Therefore, instead of writing:
const arg = 'foo ' + bar;
We should write:
const arg = `foo ${bar}`;
Restrict Types Allowed in Boolean Expressions
We may want to restrict the types allowed in boolean expressions.
This may be useful if we don’t want automatic casting of truthy and falsy values.
For instance, instead of writing:
let foo = bar || 'baz';
We may write:
let foo = typeof bar !== 'undefined' ? bar : 'baz';
Make Sure that Union Type Checks are Exhaustive
We want to make sure that union type checks are exhaustive.
This way, we make sure that we don’t miss any cases in union types.
For instance, instead of writing:
type Color = "red" | "green" | "blue";
const color = "red" as Color;
let result = 0;
switch (color) {
case "red": {
result = 1;
break;
}
}
We write:
type Color = "red" | "green" | "blue";
const color = "red" as Color;
let result = 0;
switch (color) {
case "red": {
result = 1;
break;
}
case "green": {
result = 2;
break;
}
case "blue": {
result = 3;
break;
}
}
or:
type Color = "red" | "green" | "blue";
const color = "red" as Color;
let result = 0;
switch (color) {
case "red": {
result = 1;
break;
}
default: {
result = 100;
break;
}
}
Now we took all cases into account.
Conclusion
We should use startsWith
and endsWith
to check if a string starts with or ends with something.
Also, we may want to restrict the types allowed in boolean expressions to avoid casting.
And we want to make sure that we check all the types in a union type.
Finally, if we use the +
operator, we should make sure that both operands are of the same type to prevent unexpected results.