Introduction to TypeScript: elevating the quality of our code
TypeScript, a super-set of JavaScript, has positioned itself as a priority choice for developers intent on improving the scalability and maintainability of their software projects. While JavaScript is ideal for developing quick solutions and dynamic websites, TypeScript introduces rigorous static typing that helps prevent numerous common programming errors, thus contributing to solidifying the code base and simplifying its management.
Opting for TypeScript rather than JavaScript can depend on various factors, including project complexity and the need to keep code easily manageable over time.
TypeScript, in fact, proves to be particularly advantageous for large-scale projects or those involving large teams, where precision in documenting data types and code transparency assume crucial importance.
The importance of typing
In an era where software becomes increasingly complex and integrated, the importance of expecting a specific data type cannot be underestimated. TypeScript's static typing allows developers to explicitly define the data types their variables should contain, thus reducing runtime errors and improving software quality. This precision not only facilitates code reading and maintenance, but also improves collaboration among developers, allowing the team to quickly understand the software's structure and functioning.
After this basic introduction, let's discover its features and how to use it in our project!
Basic configuration
Before proceeding, it's important to have an adequate development environment that includes support for Node.js.
mkdir mio-progetto-typescript // creiamo la cartella del nostro progetto
cd mio-progetto-typescript// installiamo typescript globalmente
npm install -g typescript
After installing TypeScript, you can initialize your project to create a tsconfig.json file that defines the compiler options.
This is an essential step to properly configure your development environment. You can proceed through the command made available after the global installation of TypeScript
tsc --initThis command automatically generates a tsconfig.json file with default configurations.
This file is fundamental in a TypeScript project because it defines how the compiler should behave during the transformation of TypeScript code into JavaScript
Its customization allows you to adapt the compilation process to your project's specific needs, influencing the output, performance, and code compatibility
// TypeScript
{
"compilerOptions": {
"target": "es2016", // Specifica la versione ECMAScript di output per il codice JavaScript compilato
"module": "commonjs", // Definisce il sistema di moduli usato nel progetto (ad es. CommonJS, ES6, etc.)
"strict": true, // Abilita una versione più rigorosa della tipizzazione, per una maggiore sicurezza del codice
"outDir": "dist", // Percorso in cui il compilatore depositerà i file JavaScript compilati dopo la build
"esModuleInterop": true, // Consente l'importazione di moduli ES6 nel progetto TypeScript
"skipLibCheck": true, // Salta la verifica dei file di definizione delle librerie per velocizzare la compilazione
"forceConsistentCasingInFileNames": true // Assicura che l'uso della capitalizzazione nei nomi dei file sia consistente
}
}
type vs interface
In TypeScript, type and interface are two constructs that allow defining data structures and contract types. Although they are similar, they present some key differences:
interface: particularly useful for defining the structure of objects that must be implemented. They are ideal for object-oriented programming in TypeScript because they can be extended or implemented by other interfaces. This allows building hierarchical and reusable type structures. Objects that implement an interface must adhere to the structure defined by that interface, which facilitates code consistency and maintainability
type: defined aliases offer greater flexibility than interfaces. They can represent not only object shapes, but also unions, intersections, and primitive types. This makes them extremely versatile for use cases requiring type combinations or specific constraints that don't easily fit the interface model
Let's see together an example that uses both interface and type:
// type-interface.ts
// definizione di un type per gli attributi base di un artista
type Artist = {
name: string;
code: string;
};
// definizione di un'interfaccia per una funzione che gestisce informazioni sugli artisti
interface ArtistInfoFunction {
(artist: Artist): string;
}
// implementazione di una funzione che corrisponde all'interfaccia ArtistInfoFunction
const showArtistInfo: ArtistInfoFunction = (artist) => {
return `Artist: ${artist.name}, code: ${artist.code}`;
};
// utilizzo della funzione con un artista specifico
const artist = { name: "artCode", code: "TypeScript" };
console.log(showArtistInfo(artist));type Artist: This type defines a structure for artist data, indicating that each artist will have a name and a "code" data of type string. Types are flexible and can be used to create composite data types, including those for functions, arrays, tuples and more.
Interface ArtistInfoFunction: This interface specifies that any function matching this interface must accept a parameter of type Artist and return a string. Using interfaces to define function signatures helps ensure that functions in different parts of the code follow the same schema, facilitating code management and maintenance
In conclusion, using interface for function signatures is particularly useful in larger and more complex scenarios where multiple functions might interact or be exchanged between different components or modules
Enum
Enums are a feature that allows defining a set of named constants, improving code readability
// TypeScript
enum Direction {
Up,
Down,
Left,
Right
}
let direzione: Direction = Direction.Up;Operators and assertions
In TypeScript, you can use type assertion when you are certain of the type of a variable in a given context, but it cannot deduce it autonomously. This is often the case when working with any types or when interfacing with untyped JavaScript libraries.
// Typescript
// esempio con string e number
let someValue: any = "artCode 2024";
let stringLength: number = (someValue as string).length;
console.log(`Lunghezza stringa: ${stringLength}`);
In this example, someValue is declared as any, but through the assertion (someValue as string), we inform TypeScript that someValue is a string, thus allowing safe access to the .length property!
After writing your code in TypeScript, it's essential to know how to transform it into executable JavaScript and how to simplify the development process through the use of the watcher.
Compilation: once you have written your script in a .ts file, you can compile the code into JavaScript using the TypeScript compiler. Open the terminal in your file's directory and type:
tsc nome-file.ts
This command converts your TypeScript file nome-file.ts into a JavaScript file nome-file.js
Execution: to execute the resulting JavaScript file, use Node.js
node nome-file.js
To make the development process more fluid, TypeScript offers a "watching" feature that automatically detects changes to TypeScript files and recompiles them in real time. This is particularly useful during active development, as it eliminates the need to manually recompile code after each change
tsc --watch nome-file.tsThis command will start a process that monitors the specified file (and all related files, if configured in tsconfig.json) and automatically recompiles the code every time a change is saved.
Using the watcher can significantly speed up your development workflow, allowing you to see the effects of your changes almost instantly without having to manually run the compilation command each time
Implementing these practices in your TypeScript development workflow, you will be able to fully leverage the language's capabilities to write safer and more maintainable code, while maintaining an efficient and responsive development environment!
And you? What do you think? Do you use or will you use TypeScript in your future projects?
