Introducció

L'API del compilador de TypeScript permet als desenvolupadors interactuar directament amb el compilador de TypeScript per crear eines personalitzades, analitzar codi, generar codi automàticament i molt més. Aquest mòdul explorarà com utilitzar aquesta API per aprofitar al màxim les capacitats de TypeScript.

Continguts

Configuració del Projecte

Instal·lació de TypeScript

Primer, assegura't de tenir TypeScript instal·lat al teu projecte. Pots fer-ho amb npm:

npm install typescript --save-dev

Configuració del tsconfig.json

Crea un fitxer tsconfig.json per configurar el compilador de TypeScript:

{
  "compilerOptions": {
    "target": "ES6",
    "module": "commonjs",
    "strict": true,
    "esModuleInterop": true
  }
}

Creació d'un Programa TypeScript

Exemple Bàsic

Per començar a utilitzar l'API del compilador, necessitem crear un programa TypeScript. Aquí tens un exemple bàsic:

import * as ts from 'typescript';

// Crea un fitxer de codi font
const sourceCode = `
    const message: string = "Hello, TypeScript!";
    console.log(message);
`;

// Crea un fitxer de codi font virtual
const sourceFile = ts.createSourceFile('example.ts', sourceCode, ts.ScriptTarget.ES2015, true);

// Crea un programa TypeScript
const program = ts.createProgram(['example.ts'], {
    target: ts.ScriptTarget.ES2015,
    module: ts.ModuleKind.CommonJS
});

// Obté el tipus checker
const checker = program.getTypeChecker();

// Analitza el fitxer de codi font
function visit(node: ts.Node) {
    if (ts.isVariableDeclaration(node)) {
        const type = checker.getTypeAtLocation(node);
        console.log(`Variable ${node.name.getText()} has type ${checker.typeToString(type)}`);
    }
    ts.forEachChild(node, visit);
}

visit(sourceFile);

Explicació del Codi

  1. Importació del Mòdul TypeScript: Importem el mòdul typescript per accedir a l'API del compilador.
  2. Creació del Fitxer de Codi Font: Definim un codi font simple com una cadena de text.
  3. Creació del Fitxer de Codi Font Virtual: Utilitzem ts.createSourceFile per crear un fitxer de codi font virtual.
  4. Creació del Programa TypeScript: Utilitzem ts.createProgram per crear un programa TypeScript.
  5. Obtenció del Type Checker: Utilitzem program.getTypeChecker per obtenir el tipus checker.
  6. Anàlisi del Fitxer de Codi Font: Definim una funció visit per recórrer l'AST i analitzar els nodes de declaració de variables.

Exploració de l'AST (Abstract Syntax Tree)

L'AST és una representació estructurada del codi font. Podem utilitzar l'API del compilador per explorar i manipular l'AST.

Exemple d'Exploració de l'AST

function printNode(node: ts.Node, indent: string = '  '): void {
    console.log(`${indent}${ts.SyntaxKind[node.kind]}`);
    node.forEachChild(child => printNode(child, indent + '  '));
}

printNode(sourceFile);

Explicació del Codi

  1. Funció printNode: Aquesta funció recorre l'AST i imprimeix el tipus de cada node amb una indentació adequada.

Transformacions de Codi

Podem utilitzar l'API del compilador per transformar el codi font. Això és útil per a la generació de codi automàticament o per a la creació de plugins de compilador.

Exemple de Transformació de Codi

function transformer<T extends ts.Node>(context: ts.TransformationContext) {
    return (rootNode: T) => {
        function visit(node: ts.Node): ts.Node {
            if (ts.isVariableDeclaration(node) && node.name.getText() === 'message') {
                return ts.factory.updateVariableDeclaration(
                    node,
                    node.name,
                    node.exclamationToken,
                    ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword),
                    ts.factory.createStringLiteral('Hello, Transformed TypeScript!')
                );
            }
            return ts.visitEachChild(node, visit, context);
        }
        return ts.visitNode(rootNode, visit);
    };
}

const result = ts.transform(sourceFile, [transformer]);
const transformedSourceFile = result.transformed[0];
const printer = ts.createPrinter();
const transformedCode = printer.printFile(transformedSourceFile);

console.log(transformedCode);

Explicació del Codi

  1. Funció transformer: Defineix una funció de transformació que modifica el valor de la variable message.
  2. Transformació del Fitxer de Codi Font: Utilitza ts.transform per aplicar la transformació al fitxer de codi font.
  3. Impressió del Codi Transformat: Utilitza ts.createPrinter per imprimir el codi transformat.

Exercicis Pràctics

Exercici 1: Anàlisi de Funcions

Crea un programa que analitzi un fitxer TypeScript i imprimeixi el nom i el tipus de retorn de cada funció.

Solució

function analyzeFunctions(node: ts.Node) {
    if (ts.isFunctionDeclaration(node) && node.name) {
        const type = checker.getTypeAtLocation(node);
        const signature = checker.getSignatureFromDeclaration(node);
        const returnType = checker.getReturnTypeOfSignature(signature!);
        console.log(`Function ${node.name.getText()} returns ${checker.typeToString(returnType)}`);
    }
    ts.forEachChild(node, analyzeFunctions);
}

analyzeFunctions(sourceFile);

Exercici 2: Transformació de Funcions

Crea una transformació que canviï el nom de totes les funcions anomenades oldFunction a newFunction.

Solució

function renameFunctionTransformer<T extends ts.Node>(context: ts.TransformationContext) {
    return (rootNode: T) => {
        function visit(node: ts.Node): ts.Node {
            if (ts.isFunctionDeclaration(node) && node.name?.getText() === 'oldFunction') {
                return ts.factory.updateFunctionDeclaration(
                    node,
                    node.decorators,
                    node.modifiers,
                    node.asteriskToken,
                    ts.factory.createIdentifier('newFunction'),
                    node.typeParameters,
                    node.parameters,
                    node.type,
                    node.body
                );
            }
            return ts.visitEachChild(node, visit, context);
        }
        return ts.visitNode(rootNode, visit);
    };
}

const renameResult = ts.transform(sourceFile, [renameFunctionTransformer]);
const renamedSourceFile = renameResult.transformed[0];
const renamedCode = printer.printFile(renamedSourceFile);

console.log(renamedCode);

Conclusió

En aquest mòdul, hem explorat l'API del compilador de TypeScript, incloent-hi com crear un programa TypeScript, explorar l'AST, i realitzar transformacions de codi. Aquestes habilitats són essencials per a la creació d'eines avançades i la manipulació de codi TypeScript de manera programàtica. Amb la pràctica, podràs aprofitar al màxim aquestes capacitats per millorar la teva productivitat i la qualitat del teu codi.

© Copyright 2024. Tots els drets reservats