Saltearse al contenido

TypeScript

Astro tiene compatibilidad integrada con TypeScript. Puedes importar archivos .ts y .tsx en tu proyecto de Astro, escribir código TypeScript directamente dentro del componente de Astro, e incluso utilizar un archivo de configuración astro.config.ts si así lo deseas.

Usando TypeScript, puedes prevenir errores en tiempo de ejecución al definir las formas de los objetos y componentes en tu código. Por ejemplo, si utilizas TypeScript para tipar las props de tu componente, obtendrás un error en tu editor si estableces una prop que tu componente no acepta.

No necesitas escribir código de TypeScript en tus proyectos de Astro para obtener beneficios de este. Astro siempre trata el código de tu componente como TypeScript, y la Extensión de Astro para VSCode inferirá todo lo que pueda para proporcionar autocompletado, sugerencias, y errores en tu editor.

El servidor de desarrollo de Astro no realizará ningún chequeo de tipado, pero puedes usar un script aparte para verificar errores de tipado desde la línea de comandos.

Los starter projects de Astro incluyen un archivo tsconfig.json en tu proyecto. Incluso si no escribes código TypeScript, este archivo es importante para que herramientas como Astro y VS Code sepan cómo interpretar tu proyecto. Algunas características (como importaciones de paquetes npm) no están totalmente soportadas en el editor sin un archivo tsconfig.json. Si instalas Astro manualmente, asegúrate de crear este archivo por ti mismo.

Tres plantillas extensibles del archivo tsconfig.json están incluidas con Astro: base, strict y strictest. La plantilla base habilita el soporte para características modernas de JavaScript y también es usada como base para las otras plantillas. Recomendamos usar las plantillas strict o strictest si planeas escribir TypeScript en tu proyecto. Puedes ver y comparar las tres plantillas en astro/tsconfigs/.

Para heredar una de las plantillas, usa la opción extends:

tsconfg.json
{
"extends": "astro/tsconfigs/base"
}

Adicionalmente, nuestras plantillas incluyen un archivo env.d.ts dentro de la carpeta src para proveer tipos del cliente de Vite en tu proyecto:

env.d.ts
/// <reference types="astro/client" />

Si no estás utilizando VSCode, puedes instalar el plugin de Astro TypeScript para admitir la importación de archivos .astro desde archivos .ts (lo cual puede ser útil para volver a exportar).

Ventana de terminal
npm install @astrojs/ts-plugin

Luego, agrega lo siguiente a tu archivo tsconfig.json:

tsconfig.json
"compilerOptions": {
"plugins": [
{
"name": "@astrojs/ts-plugin"
},
],
}

Para comprobar que el plugin está funcionando, crea un archivo .ts e importa un componente de Astro en él. No deberías tener mensajes de advertencia de tu editor.

Si tu proyecto utiliza componentes de otros framework, es posible que se necesiten configuraciones adicionales dependiendo el framework utilizado. Por favor revisa la documentación de TypeScript de tu framework para más información. (Vue, React, Preact, Solid)

Usa importaciones y exportaciones explícitas de tipos siempre que sea posible.

import { SomeType } from './script';
import type { SomeType } from './script';

Esto te ayudará a evitar casos extremos en los que el empaquetador de Astro intente empaquetar incorrectamente sus tipos importados como si fueran JavaScript.

Puedes configurar TypeScript para que obligue a realizar importaciones de tipos en tu archivo .tsconfig. Configura verbatimModuleSyntax a true. TypeScript verificará tus importaciones y te dirá cuando debes usar import type. Esta configuración está habilitada por defecto en todos nuestros presets.

tsconfig.json
{
"compilerOptions": {
"verbatimModuleSyntax": true
}
}

Astro es compatible con alias de importación definidos en la configuración tsconfig.json o jsconfig.json usando paths. Lee nuestra guía para saber más.

src/pages/about/nate.astro
---
import HelloWorld from '@components/HelloWorld.astro';
import Layout from '@layouts/Layout.astro';
---
tsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@components/*": ["src/components/*"],
"@layouts/*": ["src/layouts/*"]
}
}
}

Es posible que desees agregar una propiedad al objeto global. Puedes hacer esto agregando declaraciones de nivel superior usando la palabra clave declare a tu archivo env.d.ts:

env.d.ts
declare const myString: string;
declare function myFunction(): boolean;

Esto proporcionará tipado a globalThis.myString y globalThis.myFunction, así como a window.myString y window.myFunction.

Ten en cuenta que window sólo está disponible en el código del lado del cliente. globalThis está disponible tanto en el lado del servidor como en el lado del cliente, pero su valor del lado del servidor no se compartirá con el cliente.

Si sólo quieres tipar una propiedad en el objeto window, proporciona una interfaz Window en su lugar:

env.d.ts
interface Window {
myFunction(): boolean;
}

Astro soporta escribir los tipos de las propiedades de tus componentes usando TypeScript. Para habilitar esto, agrega una interfaz Props a tu componente en el frontmatter. Puedes usar una declaración export, pero no es necesaria. La Extensión de Astro para VSCode buscará automáticamente la interfaz Props y te dará soporte de TS cuando uses ese componente en otra plantilla.

src/components/HelloProps.astro
---
interface Props {
name: string;
greeting?: string;
}
const { greeting = 'Hola', name } = Astro.props;
---
<h2>{greeting}, {name}!</h2>
  • Si tu componente no recibe props ni slots, puedes utilizar type Props = Record<string, never>.
  • Si tu componente debe recibir children en el slot de forma predeterminada, puedes forzar esto usando type Props = { children: any; };.

Agregado en: astro@1.6.0

Astro tiene algunas utilidades de tipos integradas para patrones de tipos de props comunes. Estos están disponibles en la extensión astro/types.

Astro provee el tipo HTMLAttributes para verificar que las etiquetas estén usando atributos HTML válidos. Puedes usar estos tipos para ayudar a construir props en tus componentes.

Por ejemplo, si estuvieras construyendo un componente <Link>, podrías hacer lo siguiente para reflejar los atributos HTML por defecto para las etiquetas <a> en los tipos de props de tu componente.

src/components/Link.astro
---
import type { HTMLAttributes } from 'astro/types';
// usa un `type`
type Props = HTMLAttributes<'a'>;
// o extiendelo con una `interface`
interface Props extends HTMLAttributes<'a'> {
myProp?: boolean;
}
const { href, ...attrs } = Astro.props;
---
<a href={href} {...attrs}>
<slot />
</a>

También es posible extender las definiciones de JSX por defecto para agregar atributos no estándar, redeclarando el namespace astroHTML.JSX en un archivo .d.ts.

src/custom-attributes.d.ts
declare namespace astroHTML.JSX {
interface HTMLAttributes {
'data-count'?: number;
'data-label'?: string;
}
// Añade una propiedad personalizada de CSS al objeto de estilo.
interface CSSProperties {
'--theme-color'?: 'black' | 'white';
}
}

Agregado en: astro@4.3.0

Esta exportación de tipos te permite hacer referencia a las Props aceptadas por otro componente, incluso si ese componente no exporta ese tipo de Props directamente.

El siguiente ejemplo muestra el uso de la utilidad ComponentProps de astro/types para referenciar los tipos Props de un componente <Button />:

src/pages/index.astro
---
import type { ComponentProps } from 'astro/types';
import Button from "./Button.astro";
type ButtonProps = ComponentProps<typeof Button>;
---

Agregado en: astro@2.5.0

Astro incluye un helper para facilitar la construcción de componentes que pueden renderizarse como diferentes elementos HTML con total seguridad de tipos. Esto es útil para componentes como <Link> que pueden renderizarse como <a> o <button> dependiendo de las props que se le pasen.

El ejemplo a continuación implementa un componente completamente tipado y polimórfico que puede representarse como cualquier elemento HTML. El tipo HTMLTag se utiliza para garantizar que la propiedad as sea un elemento HTML válido.

---
import type { HTMLTag, Polymorphic } from 'astro/types';
type Props<Tag extends HTMLTag> = Polymorphic<{ as: Tag }>;
const { as: Tag, ...props } = Astro.props;
---
<Tag {...props} />

Inferir los tipos de getStaticPaths()

Sección titulada Inferir los tipos de getStaticPaths()

Agregado en: astro@2.1.0

Astro incluye ayudantes para trabajar con los tipos devueltos por tu función getStaticPaths() para rutas dinámicas.

Puedes obtener el tipo de Astro.params con InferGetStaticParamsType y el tipo de Astro.props con InferGetStaticPropsType:

src/pages/posts/[...slug].astro
---
import type { InferGetStaticParamsType, InferGetStaticPropsType, GetStaticPaths } from 'astro';
export const getStaticPaths = (async () => {
const posts = await getCollection('blog');
return posts.map((post) => {
return {
params: { slug: post.slug },
props: { draft: post.data.draft, title: post.data.title },
};
});
}) satisfies GetStaticPaths;
type Params = InferGetStaticParamsType<typeof getStaticPaths>;
type Props = InferGetStaticPropsType<typeof getStaticPaths>;
const { slug } = Astro.params as Params;
// ^? { slug: string; }
const { title } = Astro.props;
// ^? { draft: boolean; title: string; }
---

Para ver errores de tipos en tu editor, asegúrate de tener instalada la extensión de Astro VS Code. Ten en cuenta que los comandos astro start y astro build transpilarán el código con esbuild, pero no ejecutarán ninguna verificación de tipos. Para evitar que tu código se compile si contiene errores de TypeScript, cambia tu script de “compilación” en package.json a lo siguiente:

package.json
"scripts": {
"build": "astro build",
"build": "astro check && astro build",
},
Lee más sobre las importaciones de archivos .ts en Astro.
Lee más sobre la configuración de TypeScript.

Errores usando múltiples frameworks JSX a la vez

Sección titulada Errores usando múltiples frameworks JSX a la vez

Puedes tener errores al utilizar múltiples frameworks JSX en el mismo proyecto, ya que cada framework requiere diferentes, y algunas veces, conflictivas configuraciones dentro del archivo tsconfig.json.

Solución: Establece la configuración jsxImportSource a react (por defecto), preact o solid-js dependiendo cuál sea el framework más utilizado. Luego, usa un comentario pragma dentro de cada archivo conflictivo de un framework distinto al establecido anteriormente.

Para la configuración por defecto jsxImportSource: react, deberías hacer lo siguiente:

// Para Preact
/** @jsxImportSource preact */
// Para Solid
/** @jsxImportSource solid-js */