Archivos de declaración de TypeScript

El archivo de declaración es eltraductor entre TypeScript y las librerías JavaScript,que le dice a TypeScript qué funcionalidades expone una librería JavaScript, qué tipos tienen los parámetros y qué tipo de valor devuelve.


Primero empecemos con un problema

Supongamos que estás escribiendo un proyecto en TypeScript y necesitas importar una librería JavaScript de terceros (por ejemplo, jQuery). Podrías escribir un código como este:

$('#foo');
// o 
jQuery('#foo');

Este código no tiene ningún problema en un proyecto de JavaScript puro, pero en un archivo TypeScript generará un error directamente:

jQuery('#foo');

// index.ts(1,1): error TS2304: Cannot find name 'jQuery'.

¿Por qué genera un error? Porque TypeScript no reconoce$yjQueryqué es.

La función principal de TypeScript es la verificación de tipos: en la fase de compilación necesita saber el tipo de cada variable y cada función. Pero jQuery es una librería de JavaScript puro, sin información de tipos, por lo que TypeScript, naturalmente, no puede entenderla.


Solución rápida: la palabra clave `declare`

La forma más sencilla es usardeclarela palabra clave `declare` para indicar manualmente a TypeScript: «Esta variable existe, su tipo es el siguiente»:

declare var jQuery: (selector: string) => any;

jQuery('#foo');

El significado de esta línea de código es: declarar una variablejQuery, que es una función, que recibe unstringparámetro de tipo `string`, y cuyo valor de retorno puede ser de cualquier tipo (any)。

`any`). Ahora TypeScript no dará error, porque el compilador ya sabe qué tipo es jQuery.

declareLos tipos declarados con la palabra clave `declare` solo tienen efecto en la fase de compilación; se eliminan por completo en el código JavaScript compilado y no afectan el comportamiento en tiempo de ejecución.

El código JavaScript compilado del ejemplo anterior es:

jQuery('#foo');

Se puede ver quedeclarela declaración `declare` desaparece, quedando solo el código de llamada real.

perodeclareEsto solo puede resolver problemas puntuales de un solo archivo. Si una librería tiene muchos métodos y clases, escribir `declare` a mano en cada archivo no es realista. Aquí es donde los archivos de declaración son útiles.


Archivo de declaración: la solución definitiva

Un archivo de declaración consiste en poner todas lasdeclaredeclaraciones `declare` juntas en un archivo separado; cualquier archivo TypeScript del proyecto puede referenciarlo.

Convención de nombres de archivos

Los archivos de declaración usan uniformemente el sufijo.d.ts`.d.ts`,dque significa declaration (declaración). Por ejemplo:

ejemplo.d.ts

Sintaxis básica

La sintaxis para declarar un módulo es la siguiente:

declare module Module_Name {
}

En un archivo TypeScript, se incluye el archivo de declaración mediante la directiva de triple barra oblicua:

/// <reference path = "ejemplo.d.ts" />

La directiva de triple barra oblicua es una sintaxis exclusiva de TypeScript que se utiliza para indicar al compilador que debe incluir el archivo de declaración especificado al compilar.

Los archivos de declaración de muchas librerías populares de terceros (como jQuery, Lodash) ya están mantenidos por la comunidad y están almacenados en elDefinitelyTypedproyecto `DefinitelyTyped`. Solo necesitas instalar el correspondiente@types/xxxpaquete `@types` mediante npm y ya puedes usarlo, sin necesidad de escribirlo manualmente.


Ejemplo completo: crear un archivo de declaración desde cero

A continuación, mediante un ejemplo completo, se demuestra todo el flujo de creación y uso de un archivo de declaración.

Todo el proceso involucra los siguientes archivos:

ArchivoFunción
CalcThirdPartyJsLib.jsLibrería JavaScript de terceros (JS puro, sin información de tipos)
Calc.d.tsArchivo de declaración (escrito manualmente, describe los tipos de la librería)
CalcTest.tsCódigo de negocio TypeScript (referencia el archivo de declaración y llama a la librería)
CalcTest.jsResultado de compilación (archivo JS compilado por tsc)
ejemplo.htmlPágina final que se ejecuta en el navegador

Primer paso: crear una librería JavaScript de terceros

Supongamos que tenemos una librería de terceros que proporciona la función de suma acumulativa. Utiliza el espacio de nombresEjemplo`Ejemplo` para organizar el código y evitar conflictos de nombres de variables:

Código del archivo CalcThirdPartyJsLib.js:

// Ruta del archivo: CalcThirdPartyJsLib.js
// Esta es una librería JavaScript de terceros simulada

// Declara la variable de espacio de nombres Ejemplo (si no existe, crea un objeto vacío)
var Ejemplo;

// Usa una función de ejecución inmediata (IIFE) para encapsular el código y evitar que las variables internas se filtren al ámbito global
(function(Ejemplo) {
    // Constructor Calc, utilizado para crear objetos calculadora
    var Calc = (function () {
        function Calc() {
            // Actualmente no necesita parámetros de inicialización; se conserva el constructor para futuras extensiones
        }
    })

    // Método doSum: calcula la suma de todos los enteros desde 0 hasta limit
    // limit (obligatorio): valor límite superior de la suma, incluye el propio valor
    // Ejemplo: cuando limit=10, calcula 0+1+2+...+10 = 55
    Calc.prototype.doSum = function (limit) {
        var sum = 0;

        for (var i = 0; i <= limit; i++) {
            sum = sum + i;
        }
        return sum;
    }

    // Monta el constructor Calc en el espacio de nombres Ejemplo
    // De esta manera, el exterior puede crear instancias mediante new Ejemplo.Calc()
    Ejemplo.Calc = Calc;
    return Calc;
})(Ejemplo || (Ejemplo = {}));

// Código de autocomprobación interno de la librería
var test = new Ejemplo.Calc();

Esta librería utiliza un patrón común: la función de ejecución inmediata (IIFE). En términos simples, consiste en envolver el código en una función y ejecutarla inmediatamente, de modo que las variables definidas dentro de la función no escapan al exterior, evitando conflictos de nombres con otras variables.

Segundo paso: escribir el archivo de declaración

Ahora tenemos una librería JS, pero no tiene ninguna información de tipos. Necesitamos crear un archivo de declaración que solo describa la "forma" de la librería (qué clases tiene, qué métodos tiene, qué tipos tienen los parámetros y los valores de retorno), pero sin incluir ninguna lógica de código real:

Código del archivo Calc.d.ts:

// Ruta del archivo: Calc.d.ts
// Este es un archivo de declaración: solo contiene información de tipos, no contiene ningún código ejecutable

// Declara el módulo Ejemplo, que corresponde al espacio de nombres Ejemplo en la librería JS
declare module Ejemplo {
   // Declara la clase Calc, informando a TypeScript que esta clase se puede instanciar con new
   export class Calc {
      // Declara el método doSum: recibe un parámetro number y devuelve un number
      // Nota: aquí solo se declara la firma del método, sin cuerpo de método (llaves)
      doSum(limit: number): number;
   }
}

La mayor diferencia entre un archivo de declaración y un archivo .ts normal es que el archivo de declaración solo tiene firmas de tipos, sin código de implementación. Solo responde "cómo es esta función", no "qué hace esta función".

Tercer paso: usar en código TypeScript

Ahora escribimos el código de negocio. Después de referenciar el archivo de declaración, podemos usar esta librería JS de terceros como si fuera una librería TypeScript nativa:

Código del archivo CalcTest.ts:

// Ruta del archivo: CalcTest.ts
// Directiva de triple barra oblicua: indica al compilador de TypeScript que incluya el archivo de declaración
/// <reference path = "Calc.d.ts" />

// Crea una instancia de Calc; TypeScript ahora puede identificar correctamente el tipo de obj
var obj = new Ejemplo.Calc();

// obj.doSum("Hello"); // ¡Error de compilación! "Hello" es un string, mientras que doSum exige un parámetro number
console.log(obj.doSum(10)); // Llamada correcta: pasar 10, se espera obtener 55

Observa la línea que está comentada:

obj.doSum("Hello");

Si descomentas esa línea, TypeScript dará un error directamente al compilar, porque el archivo de declaración ya ha establecido que doSum solo acepta parámetros de tipo number. Así es como la verificación de tipos te protege: los errores se muestran al escribir el código, en lugar de provocar un fallo cuando la página se ejecuta en el navegador.

Cuarto paso: compilar TypeScript

Usa el comando `tsc` que viene con TypeScripttscpara compilar:

tsc CalcTest.ts

Después de compilar se generará elCalcTest.jsarchivo `CalcTest.js`, cuyo contenido es el siguiente:

Resultado de compilación CalcTest.js:

// Ruta del archivo: CalcTest.js (generado automáticamente por el comando tsc)
/// <reference path = "Calc.d.ts" />
var obj = new Ejemplo.Calc();
//obj.doSum("Hello"); // Error de compilación
console.log(obj.doSum(10)); // Resultado de la ejecución: se imprime 55 en la consola

Se puede ver que las directivas de triple barra y la información de tipos en los archivos de declaración han desaparecido del producto compilado, dejando solo código JavaScript puro en ejecución.

Quinto paso: ejecutar en el navegador

Finalmente, cree una página HTML que enlace todos los archivos JS:

Ejemplo

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Tutorial Ejemplo (example.com)</title>
<!-- Paso 1: Cargar la biblioteca de terceros para que el espacio de nombres Ejemplo esté disponible globalmente -->
<script src = "CalcThirdPartyJsLib.js"></script>
<!-- Paso 2: Cargar el código de negocio compilado -->
<script src = "CalcTest.js"></script>
</head>
<body>
    <h1>Prueba del archivo de declaración</h1>
    <p>Ejemplo lo prueba.</p>
</body>
</html>

Abra este archivo HTML en un navegador, abra la consola (F12), y podrá ver el resultado de salida:

55

Este es el valor de retorno de doSum(10): 0+1+2+...+10 = 55.

声明文件测试结果


Resumen

Un archivo de declaración es esencialmente un «manual de tipos» que permite a TypeScript comprender y verificar bibliotecas de JavaScript puro.

Todo el flujo de trabajo se puede resumir en tres pasos:

1. Obtener una biblioteca JS y analizar qué API expone.

2. Escribir.d.tsel archivo de declaración, que describe las firmas de tipo de estas API.

3. Hacer referencia al archivo de declaración en el código TypeScript para disfrutar de una completa protección de verificación de tipos.

Para bibliotecas de terceros de uso común en el desarrollo diario, la gran mayoría ya tiene archivos de declaración listos (a través denpm install @types/xxxinstalación). Solo cuando se utilizan bibliotecas muy poco conocidas o bibliotecas privadas internas, es necesario escribir manualmente archivos de declaración.

Otras extensiones