Professional Documents
Culture Documents
Published in ITNEXT
Save
Content
Intro 830 20
https://itnext.io/mastering-typescript-21-best-practices-for-improved-code-quality-2f7615e1fdc3 1/20
24/04/2023, 21:02 🔥 Mastering TypeScript: 20 Best Practices for Improved Code Quality | by Vitalii Shevchuk | ITNEXT
Best Practice 1: Strict Type Checking
Conclusion
Learn More
https://itnext.io/mastering-typescript-21-best-practices-for-improved-code-quality-2f7615e1fdc3 2/20
24/04/2023, 21:02 🔥 Mastering TypeScript: 20 Best Practices for Improved Code Quality | by Vitalii Shevchuk | ITNEXT
Intro
TypeScript is a widely used, open-source programming language that is perfect for
modern development. With its advanced type system, TypeScript allows developers
to write code that is more robust, maintainable, and scalable. But, to truly harness
the power of TypeScript and build high-quality projects, it’s essential to understand
and follow best practices. In this article, we’ll dive deep into the world of TypeScript
and explore 20 best practices for mastering the language. These best practices cover
a wide range of topics and provide concrete examples of how to apply them in real-
world projects. Whether you’re just starting out or you’re an experienced TypeScript
developer, this article will provide valuable insights and tips to help you write clean,
efficient code.
So, grab a cup of coffee ☕️, and let’s get started on our journey to mastering
TypeScript!
Strict type checking is all about making sure that the types of your variables match
the types you expect them to be. This means that if you declare a variable to be of
type string , TypeScript will make sure that the value assigned to that variable is
indeed a string and not a number, for example. This helps you to catch errors early
on and make sure your code is working as intended.
Here’s an example of how strict type checking can save you from a common
mistake:
https://itnext.io/mastering-typescript-21-best-practices-for-improved-code-quality-2f7615e1fdc3 3/20
24/04/2023, 21:02 🔥 Mastering TypeScript: 20 Best Practices for Improved Code Quality | by Vitalii Shevchuk | ITNEXT
By following this best practice, you will be able to catch errors early on and make
sure that your code is working as intended, saving you time and frustration in the
long run.
For example, in the following code snippet, TypeScript will automatically infer that
the type of name is a string :
Type inference is especially useful when you are working with complex types or
when you are initializing a variable with a value that is returned from a function.
But remember, type inference is not a magic wand, sometimes it’s better to be
explicit with types, especially when working with complex types or when you want
to make sure that a specific type is used.
There are several linters available for TypeScript, such as TSLint and ESLint, that
can help you to enforce a consistent code style and catch potential errors. These
linters can be configured to check for things like missing semicolons, unused
variables, and other common issues.
interface User {
name: string;
age: number;
}
let user: User = {name: "John", age: 25};
Interfaces also make it easier to refactor your code, by ensuring that all the places
where a certain type is used are updated at once.
https://itnext.io/mastering-typescript-21-best-practices-for-improved-code-quality-2f7615e1fdc3 5/20
24/04/2023, 21:02 🔥 Mastering TypeScript: 20 Best Practices for Improved Code Quality | by Vitalii Shevchuk | ITNEXT
TypeScript allows you to create custom types using a feature called type aliases. The
main difference between features type alias and interface is that type alias
creates a new name for the type, whereas interface creates a new name for the
shape of the object.
For example, you can use a type alias to create a custom type for a point in a two-
dimensional space:
Type aliases can also be used to create complex types, such as a union type or an
intersection type.
https://itnext.io/mastering-typescript-21-best-practices-for-improved-code-quality-2f7615e1fdc3 6/20
24/04/2023, 21:02 🔥 Mastering TypeScript: 20 Best Practices for Improved Code Quality | by Vitalii Shevchuk | ITNEXT
One of the main advantages of using tuples is that they provide a way to express a
specific type relationship between the elements in the collection.
In addition, you can use destructuring assignment to extract the elements of a tuple
and assign them to variables:
One best practice when using any is to limit its usage to specific cases where the
type is truly unknown, such as when working with third-party libraries or
dynamically generated data. Additionally, it’s a good idea to add type assertions or
type guards to ensure the variable is being used correctly. And when possible, try to
narrow down the type of the variable as much as you can.
For example:
https://itnext.io/mastering-typescript-21-best-practices-for-improved-code-quality-2f7615e1fdc3 7/20
24/04/2023, 21:02 🔥 Mastering TypeScript: 20 Best Practices for Improved Code Quality | by Vitalii Shevchuk | ITNEXT
logData(user); // { name: "John", age: 30 }
logData(numbers); // [1, 2, 3]
Another best practice is to avoid using any in function return types and function
arguments, as it can weaken the type safety of your code. Instead, you can use a
type that is more specific or use a type that is more general like unknown or object
Unlike any , when you use the unknown type, TypeScript will not allow you to
perform any operation on a value unless you first check its type. This can help you
to catch type errors at compile-time, instead of at runtime.
For example, you can use the unknown type to create a more type-safe function:
You can also use the unknown type to create more type-safe variables:
https://itnext.io/mastering-typescript-21-best-practices-for-improved-code-quality-2f7615e1fdc3 8/20
24/04/2023, 21:02 🔥 Mastering TypeScript: 20 Best Practices for Improved Code Quality | by Vitalii Shevchuk | ITNEXT
For example, consider the following function that throws an error if the input is less
than 0:
Here, the function divide is declared to return a number, but if the denominator is
zero, it will throw an error. To indicate that this function will not return normally in
this case, you can use never as the return type:
https://itnext.io/mastering-typescript-21-best-practices-for-improved-code-quality-2f7615e1fdc3 9/20
24/04/2023, 21:02 🔥 Mastering TypeScript: 20 Best Practices for Improved Code Quality | by Vitalii Shevchuk | ITNEXT
For example, you can use the keyof operator to create a more readable and
maintainable type for an object:
interface User {
name: string;
age: number;
}
You can also use the keyof operator to create more type-safe functions that take an
object and a key as arguments:
For example, you can use an enum to define a set of possible status values for an
order:
enum OrderStatus {
Pending,
Processing,
Shipped,
Delivered,
Cancelled
https://itnext.io/mastering-typescript-21-best-practices-for-improved-code-quality-2f7615e1fdc3 10/20
24/04/2023, 21:02 🔥 Mastering TypeScript: 20 Best Practices for Improved Code Quality | by Vitalii Shevchuk | ITNEXT
}
enum OrderStatus {
Pending = 1,
Processing = 2,
Shipped = 3,
Delivered = 4,
Cancelled = 5
}
Always name an enum with the first capital letter and the name has to be in
singular form, as a part of the naming convention.
For example, you can use a namespace to group all the code related to a specific
feature:
namespace OrderModule {
export class Order { /* … */ }
export function cancelOrder(order: Order) { /* … */ }
export function processOrder(order: Order) { /* … */ }
}
let order = new OrderModule.Order();
OrderModule.cancelOrder(order);
https://itnext.io/mastering-typescript-21-best-practices-for-improved-code-quality-2f7615e1fdc3 11/20
24/04/2023, 21:02 🔥 Mastering TypeScript: 20 Best Practices for Improved Code Quality | by Vitalii Shevchuk | ITNEXT
You can also use namespaces to prevent naming collisions by providing a unique
name for your code:
namespace MyCompany.MyModule {
export class MyClass { /* … */ }
}
It’s important to note that namespaces are similar to modules, but they are used to
organize the code and prevent naming collisions, while modules are used to load
and execute the code.
For example, you can use the Pick utility type to extract a subset of properties from
an object type:
You can also use the Exclude utility type to remove properties from an object type:
You can use the Partial utility type to make all properties of a type optional:
https://itnext.io/mastering-typescript-21-best-practices-for-improved-code-quality-2f7615e1fdc3 12/20
24/04/2023, 21:02 🔥 Mastering TypeScript: 20 Best Practices for Improved Code Quality | by Vitalii Shevchuk | ITNEXT
interface Point {
x: number;
y: number;
}
let point: Readonly<Point> = {x: 0, y: 0};
point.x = 1; // TypeScript will raise an error because "point.x" is read-only
The ReadonlyArray is similar to Readonly but for arrays. It makes an array read-only,
and it can’t be modified after it’s created.
https://itnext.io/mastering-typescript-21-best-practices-for-improved-code-quality-2f7615e1fdc3 13/20
24/04/2023, 21:02 🔥 Mastering TypeScript: 20 Best Practices for Improved Code Quality | by Vitalii Shevchuk | ITNEXT
help you to narrow down the type of a variable based on certain conditions.
Type guards can also be used with the “in” operator, the typeof operator and the
instanceof operator.
For example, you can use a generic function to create an array of any type:
return result;
}
https://itnext.io/mastering-typescript-21-best-practices-for-improved-code-quality-2f7615e1fdc3 14/20
24/04/2023, 21:02 🔥 Mastering TypeScript: 20 Best Practices for Improved Code Quality | by Vitalii Shevchuk | ITNEXT
You can also use generics to create a class that can work with any type of data:
class GenericNumber<T> {
zeroValue: T;
add: (x: T, y: T) => T;
}
For example, you can use the infer keyword to create a more precise type for a
function that returns an array of a specific type:
You can also use the infer keyword to create more precise types for a function that
returns an object with a specific property:
For example, you can use a conditional type to extract the return type of a function:
You can also use conditional types to extract the properties of an object type that
meet a certain condition:
For example, you can use a mapped type to create a new type that represents the
readonly version of an existing type:
You can also use a mapped type to create a new type that represents the optional
version of an existing type:
https://itnext.io/mastering-typescript-21-best-practices-for-improved-code-quality-2f7615e1fdc3 16/20
24/04/2023, 21:02 🔥 Mastering TypeScript: 20 Best Practices for Improved Code Quality | by Vitalii Shevchuk | ITNEXT
Mapped types can be used in different ways: to create new types, to add or remove
properties from an existing type, or to change the type of the properties of an
existing type.
class Calculator {
@logMethod
add(x: number, y: number): number {
return x + y;
}
}
You can also use decorators to add metadata to a class, method or property, which
can be used at runtime.
https://itnext.io/mastering-typescript-21-best-practices-for-improved-code-quality-2f7615e1fdc3 17/20
24/04/2023, 21:02 🔥 Mastering TypeScript: 20 Best Practices for Improved Code Quality | by Vitalii Shevchuk | ITNEXT
@setApiPath("/users")
class UserService {
// …
}
console.log(new UserService().apiPath); // "/users"
Conclusion
Whether you are a beginner or an experienced TypeScript developer, I hope that
this article has provided valuable insights and tips to help you write clean, efficient
code.
Remember, best practices are guidelines, not hard rules. Always use your own
judgment and common sense when writing code. And keep in mind that, as
TypeScript evolves and new features are introduced, the best practices may change,
so stay up to date and be open to learning new things.
We hope that you have found this article helpful and that it has inspired you to
become a better TypeScript developer. Happy coding! Don’t forget to clap,
comment, follow and subscribe, this will share TypeScript best practices with more
people and improve your karma!
Learn More
https://itnext.io/mastering-typescript-21-best-practices-for-improved-code-quality-2f7615e1fdc3 18/20
24/04/2023, 21:02 🔥 Mastering TypeScript: 20 Best Practices for Improved Code Quality | by Vitalii Shevchuk | ITNEXT
Subscribe
https://itnext.io/mastering-typescript-21-best-practices-for-improved-code-quality-2f7615e1fdc3 19/20
24/04/2023, 21:02 🔥 Mastering TypeScript: 20 Best Practices for Improved Code Quality | by Vitalii Shevchuk | ITNEXT
Get the Medium app
https://itnext.io/mastering-typescript-21-best-practices-for-improved-code-quality-2f7615e1fdc3 20/20