TypeScript - Introducció i Característiques Principals¶
1. Què és TypeScript?¶
TypeScript és un llenguatge de programació de codi obert desenvolupat per Microsoft que constitueix un superset de JavaScript. Afegeix tipat estàtic i altres característiques avançades que es compilen a JavaScript pur.
Característiques principals:¶
- Tipat estàtic opcional
- Compatibilitat total amb JavaScript
- Compilat a JavaScript compatible amb qualsevol navegador
- Suport per a ESMAScript més recent
- Eines de desenvolupament millorades
2. Configuració i Instal·lació¶
Instal·lació global:¶
npm install -g typescript
Configuració del projecte:¶
# Inicialitza un projecte TypeScript
tsc --init
Estructura bàsica del tsconfig.json:¶
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"moduleResolution": "node"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
3. Tipus de Dades Bàsics¶
Tipus primitius:¶
// Strings
let nom: string = "Anna";
let cognom: string = 'Garcia';
// Numbers
let edat: number = 25;
let decimal: number = 3.14;
// Booleans
let esActiu: boolean = true;
let estaValidat: boolean = false;
// Arrays
let llistaNoms: string[] = ["Anna", "Pere", "Maria"];
let numeros: Array<number> = [1, 2, 3, 4, 5];
// Tuples
let persona: [string, number] = ["Anna", 25];
// Enum
enum Color {
Vermell = "RED",
Verd = "GREEN",
Blau = "BLUE"
}
// Any (evitar quan sigui possible)
let variableDynamic: any = "pot ser qualsevol cosa";
variableDynamic = 42;
// Void (funcions que no retornen res)
function mostrarMissatge(): void {
console.log("Hola món!");
}
// Null i Undefined
let nul: null = null;
let indefinit: undefined = undefined;
4. Tipat Avançat¶
Unions de tipus:¶
let id: string | number;
id = "ABC123"; // Vàlid
id = 123; // Vàlid
// id = true; // Error
// Literal types
let direccio: "nord" | "sud" | "est" | "oest";
direccio = "nord"; // Vàlid
// direccio = "centre"; // Error
// Type Aliases
type ID = string | number;
type Coordenades = [number, number];
type Usuari = {
id: ID;
nom: string;
email: string;
};
Interfaces:¶
interface Persona {
readonly id: number; // Propietat només de lectura
nom: string;
edat?: number; // Propietat opcional
readonly dataCreacio: Date;
}
interface Empleat extends Persona {
departament: string;
salari: number;
}
const usuari: Persona = {
id: 1,
nom: "Anna",
dataCreacio: new Date()
};
// usuari.id = 2; // Error - readonly
Generics:¶
function identitat<T>(valor: T): T {
return valor;
}
const resultat = identitat<string>("Hola");
const numero = identitat(42); // Inferència de tipus
interface Caixa<T> {
contingut: T;
}
const caixaString: Caixa<string> = { contingut: "text" };
const caixaNumber: Caixa<number> = { contingut: 42 };
5. Funcions¶
Definició de funcions:¶
// Funció bàsica
function suma(a: number, b: number): number {
return a + b;
}
// Funció amb paràmetres opcionals
function saludar(nom: string, titol?: string): string {
return titol ? `Hola ${titol} ${nom}` : `Hola ${nom}`;
}
// Funció amb valor per defecte
function multiplicar(a: number, b: number = 1): number {
return a * b;
}
// Funció amb paràmetres rest
function concatenar(...paraules: string[]): string {
return paraules.join(" ");
}
// Arrow functions
const dividir = (a: number, b: number): number => a / b;
// Function overloading
function processar(input: string): string;
function processar(input: number): number;
function processar(input: string | number): string | number {
if (typeof input === "string") {
return input.toUpperCase();
}
return input * 2;
}
6. Classes i Objectes¶
Classes bàsiques:¶
class Persona {
// Propietats
public nom: string;
protected edat: number;
private id: number;
// Constructor
constructor(nom: string, edat: number, id: number) {
this.nom = nom;
this.edat = edat;
this.id = id;
}
// Mètodes
public saludar(): string {
return `Hola, soc ${this.nom}`;
}
// Getters i Setters
public get getId(): number {
return this.id;
}
}
// Herència
class Empleat extends Persona {
private departament: string;
constructor(nom: string, edat: number, id: number, departament: string) {
super(nom, edat, id);
this.departament = departament;
}
public obtenirDetalls(): string {
return `${this.nom} treballa a ${this.departament}`;
}
}
// Classes abstractes
abstract class Forma {
abstract calcularArea(): number;
descripcio(): string {
return "Això és una forma geomètrica";
}
}
class Cercle extends Forma {
constructor(private radi: number) {
super();
}
calcularArea(): number {
return Math.PI * this.radi ** 2;
}
}
Modificadors d'accés moderns:¶
class Usuari {
constructor(
public readonly id: number,
public nom: string,
private email: string,
protected estaActiu: boolean = true
) {}
}
7. Mòduls i Organització de Codi¶
Exportació:¶
// Export per defecte
export default class Comptador {
private valor: number = 0;
incrementar(): void {
this.valor++;
}
}
// Exportacions nominades
export const PI = 3.1416;
export function calcularArea(radi: number): number {
return PI * radi * radi;
}
export interface Punt {
x: number;
y: number;
}
Importació:¶
// Import per defecte
import Comptador from './comptador';
// Importacions nominades
import { PI, calcularArea, type Punt } from './matematiques';
// Import de tot
import * as Matematiques from './matematiques';
8. Eines i Configuracions Modernes¶
Compilació i execució:¶
# Compilar TypeScript
tsc
# Compilar en mode watch
tsc --watch
# Compilar projecte específic
tsc -p tsconfig.json
# Executar amb ts-node
npx ts-node arxiu.ts
Configuració recomanada per a Angular:¶
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"lib": ["ES2022", "DOM"],
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"moduleResolution": "node",
"baseUrl": "./",
"paths": {
"@/*": ["src/*"]
}
}
}
9. Novetats de TypeScript Modern¶
Optional Chaining:¶
const usuari = {
perfil: {
nom: "Anna",
adreca: {
ciutat: "Barcelona"
}
}
};
const ciutat = usuari?.perfil?.adreca?.ciutat; // "Barcelona"
const codiPostal = usuari?.perfil?.adreca?.codiPostal; // undefined
Nullish Coalescing:¶
const valor = null ?? "valor per defecte"; // "valor per defecte"
const zero = 0 ?? 42; // 0 (no 42, perquè 0 no és null/undefined)
Assertions de tipus:¶
// As-serció de tipus
const element = document.getElementById("boto") as HTMLButtonElement;
// As-serció no-null
const valor = document.getElementById("input")!;
// As-serció const
const config = {
color: "vermell",
mida: "gran"
} as const;
Satisfies operator (TypeScript 4.9+):¶
const configuracio = {
color: "vermell",
mida: "gran"
} satisfies Record<string, string>;
10. Millors Pràctiques¶
1. Utilitza tipat estricte:¶
// ❌ Evita
let variable: any;
// ✅ Correcte
let variable: string;
2. Prefereix interfaces per a objectes:¶
// ✅ Interface per a objectes
interface Usuari {
id: number;
nom: string;
}
// ✅ Type aliases per a unions
type ID = number | string;
3. Utilitza generics apropiadament:¶
// ✅ Generic reutilitzable
function obtenirPropietat<T, K extends keyof T>(objecte: T, clau: K): T[K] {
return objecte[clau];
}
4. Aprofita la inferència de tipus:¶
// ✅ TypeScript infereix el tipus
const noms = ["Anna", "Pere", "Maria"]; // string[]
const numeros = [1, 2, 3]; // number[]