Tu Primera Aplicación Vue 3 usando TypeScript
Tags: javascriptvue
Published: 2020-12-22 17:30:28

---
title: Tu Primera Aplicación Vue 3 usando TypeScript
published: true
date: 2020-12-21 17:56:59 UTC
tags: javascriptvue
canonical_url: https://www.thisdot.co/blog/tu-primera-aplicacion-vue-3-usando-typescript
---

Vue 3 se ha reconstruido desde cero usando TypeScript. Desde Vue v2, Vue ha soportado TypeScript y aún lo hace. Sin embargo, en estos días se siente cierto entusiasmo e interés por desarrollar aplicaciones con Vue usando TypeScript.

Sin lugar a dudas, desarrollar aplicaciones JavaScript con TypeScript es como un salvavidas. TypeScript, además de las muchas ventajas que trae, proporciona seguridad con los tipos. Tú estarás feliz, tu IDE estará feliz y, por supuesto, hace que la escritura de JavaScript sea más interesante y robusta.

Este artículo te trae una guía paso a paso para crear una aplicación Vue 2, agrega compatibilidad con TypeScript, actualiza la aplicación a Vue 3 RC 5, compila la aplicación, corrige algunos errores comunes en la etapa de compilación y finalmente se asegura que la aplicación pueda ejecutarse en el navegador.

> Para acceder al código fuente que acompaña a este artículo, ve al [Repositorio en GitHub](https://github.com/bhaidar/vue-typescript).

**Nota** - Este artículo se aplica a aplicaciones Vue 2 existentes que deseen actualizar a Vue 3 y agregar TypeScript, así como a cualquier aplicación nueva.

## Demo

Comencemos creando una aplicación Vue 2 y siguiendo los pasos necesarios.

### Creando una Nueva App

Como sugiere el subtítulo, crearemos una aplicación Vue 2 utilizando la CLI de Vue.

##### Paso 1: Instala el paquete @vue/cli

Abre una terminal y ejecuta el comando:

```
npm install -g @vue/cli
```

##### Paso 2: Crea una nueva App Vue 2

```
vue create vue-ts
```

Selecciona el `default preset`(ajuste predeterminado) cuando se solicite. La CLI(Herramienta de línea de comandos) hace un _scaffolding_ de los archivos y también inicializa un repositorio Git para la aplicación.

##### Paso 3: Ejecuta la aplicación

Ejecuta la aplicación para asegurarte de que esta funciona correctamente:

```
cd vue-ts
npm run serve
```

¡Deberías tener una App corriendo ahora!

### Agregando el Soporte de TypeScript

Ejecutemos el siguiente comando para agregar el soporte de TypeScript en nuestra app.

```
vue add typescript
```

El comando anterior descarga e instala el _plugin_(complemento) [@vue/cli-plugin-typescript](https://www.npmjs.com/package/@vue/cli-plugin-typescript) para brindar compatibilidad con TypeScript en nuestra aplicación.

Una vez instalado, se harán algunas preguntas que se muestran en la **Figura 1**.

[![agregando-typescript](https://images.ctfassets.net/zojzzdop0fzx/7wrIIZ7cpbhOAGqCrRDk21/c28582e2cc33e9c9698cee81665c4879/Screenshot_2020-08-11_at_4.27.38_PM.png)](https://images.ctfassets.net/zojzzdop0fzx/7wrIIZ7cpbhOAGqCrRDk21/c28582e2cc33e9c9698cee81665c4879/Screenshot_2020-08-11_at_4.27.38_PM.png)

| Preguntas en la Instalación |
| --- |
| **Use class-style component syntax?** Yes |
| **Use Babel alongside TypeScript?** Yes |
| **Convert all .js files to .ts?** Yes |
| **Allow .js files to be compiled?** Yes |
| **Skip type checking of all declaration files?** Yes |

Entre las muchas cosas que el _plugin_ agrega a la aplicación, es importante señalar el archivo `tsconfig.json` en la raíz de la carpeta de la aplicación. TypeScript usa este archivo para personalizar el proceso de compilación y te da la oportunidad de hacerlo según tus necesidades. Las siguientes configuraciones son recomendadas por el equipo de Vue. Sin embargo, siéntete libre de agregar o cambiar cosas como mejor lo consideres.

> Para una lista completa de todas las opciones disponibles para este archivo, revisa este link [tsconfig.json](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html)

```
{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "strict": true,
    "jsx": "preserve",
    "importHelpers": true,
    "moduleResolution": "node",
    "experimentalDecorators": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "sourceMap": true,
    "baseUrl": ".",
    "types": [
      "webpack-env"
    ],
    "paths": {
      "@/*": [
        "src/*"
      ]
    },
    "lib": [
      "esnext",
      "dom",
      "dom.iterable",
      "scripthost"
    ]
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx",
    "src/**/*.vue",
    "tests/**/*.ts",
    "tests/**/*.tsx"
  ],
  "exclude": [
    "node_modules"
  ]
}
```

Finalmente, asegúrate de confirmar sus cambios en Git con un _commit_ antes de continuar.

### Actualizar la aplicación a Vue 3

Ahora que la aplicación soporta la definición de componentes Vue en TypeScript, sigamos adelante y actualicemos la aplicación a Vue 3.

##### Paso 1: Agrega el _plugin_ Vue-Next

Abre una terminal y navega hasta la carpeta raíz de nuestra aplicación. Luego, ejecuta el siguiente comando:

```
vue agregar vue-siguiente
```

El comando previo descarga e instala el _plugin_ [vue-cli-plugin-vue-next](https://www.npmjs.com/package/vue-cli-plugin-vue-next) para hacer un _upgrade_(actualizar) la aplicación a Vue 3.

La **Figura 2** muestra todos los pasos que ha seguido la CLI(Interfaz de línea de comandos) para realizar la actualización.

[![agrega-vue-next](https://images.ctfassets.net/zojzzdop0fzx/4RRTH0TJB6S8d0aB8951gO/8c13257da1cdd2b2689b4646078c86de/Screenshot_2020-08-11_at_5.24.10_PM.png)](https://images.ctfassets.net/zojzzdop0fzx/4RRTH0TJB6S8d0aB8951gO/8c13257da1cdd2b2689b4646078c86de/Screenshot_2020-08-11_at_5.24.10_PM.png)

Abre el archivo `package.json` y asegúrate que las secciones de `dependencies` y `dev-dependencies` sean similares al contenido siguiente:

```
"dependencies": {
  "core-js": "^3.6.5",
  "vue": "^3.0.0-rc.5"
},
"devDependencies": {
  "@vue/cli-plugin-babel": "~4.4.0",
  "@vue/cli-plugin-eslint": "~4.4.0",
  "@vue/cli-service": "~4.4.0",
  "@vue/compiler-sfc": "^3.0.0-rc.5",
  "babel-eslint": "^10.1.0",
  "eslint": "^6.7.2",
  "eslint-plugin-vue": "^7.0.0-alpha.0",
  "vue-cli-plugin-vue-next": "~0.1.3"
},
```

El plugin **vue-next** pasa automáticamente por los archivos de tu aplicación y los convierte para que sean compatibles con la sintaxis de Vue 3.

##### Paso 2: Corrige las advertencias y errores

En este punto, si compilas la aplicación, verás algunas _warnings_(advertencias) y errores. Estos están relacionados principalmente con el uso de TypeScript en Vue 3. Abordemos los mismos uno por uno.

Ejecuta el siguiente comando para compilar y levantar la aplicación en el navegador:

```
npm run serve
```

El resultado se muestra a continuación:

**Advertencias** (Warnings)

```
warning in ./node_modules/vue-class-component/dist/vue-class-component.esm.js
"export 'default' (imported as 'Vue') was not found in 'vue'

warning in ./node_modules/vue-class-component/dist/vue-class-component.esm.js
"export 'default' (imported as 'Vue') was not found in 'vue'

warning in ./node_modules/vue-class-component/dist/vue-class-component.esm.js
"export 'default' (imported as 'Vue') was not found in 'vue'

warning in ./node_modules/vue-class-component/dist/vue-class-component.esm.js
"export 'default' (imported as 'Vue') was not found in 'vue'

warning in ./node_modules/vue-property-decorator/lib/vue-property-decorator.js
"export 'default' (reexported as 'Vue') was not found in 'vue'
```

**Errores**

```
TS1238: Unable to resolve signature of class decorator when called as an expression.
  Type '<VC extends VueClass<any>>(target: VC) => VC' is not assignable to type 'typeof HelloWorld'.
    Type '<VC extends VueClass<any>>(target: VC) => VC' provides no match for the signature 'new (): HelloWorld'.
    33 | import { Component, Prop, Vue } from 'vue-property-decorator';
    34 | 
  > 35 | @Component
       | ^^^^^^^^^^
    36 | export default class HelloWorld extends Vue {
    37 | @Prop() private msg!: string;
    38 | }

ERROR in src/components/HelloWorld.vue:36:41
TS2507: Type 'typeof import("/Users/bhaidar/projects/vue-ts/node_modules/vue/dist/vue")' is not a constructor function type.
    34 | 
    35 | @Component
  > 36 | export default class HelloWorld extends Vue {
       | ^^^
    37 | @Prop() private msg!: string;
    38 | }
    39 | </script>
```

Las advertencias y los errores anteriores revelan que TypeScript no puede digerir el Componente `HelloWorld` que está escrito en la antigua sintaxis de TypeScript para Vue 2. Procedamos a refactorizar este componente para usar la última sintaxis de TypeScript en Vue 3.

Actualmente, el componente `/components/HelloWorld.vue` se define de la siguiente forma:

```
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';

@Component
export default class HelloWorld extends Vue {
  @Prop() private msg!: string;
}
</script>
```

En primer lugar, note el uso de un atributo `lang = "ts"` en el elemento `<script>`. Esto define un bloque de código TypeScript en lugar de código JavaScript.

Reemplacemos este código como sigue:

```
<script lang="ts">
import { defineComponent } from 'vue';

export default defineComponent({
  name: 'HelloWorld',
  props: {
    msg: {
      type: String,
      required: false,
    },
  },
});
</script>
```

El código usa el nuevo método global `defineComponent`. Este método permite a TypeScript inferir adecuadamente los tipos dentro de las opciones del componente Vue.

El método `defineComponent` acepta un objeto como parámetro de entrada. Puede ser un objeto _Options API_ o un objeto _Composition API_.

Ahora que se ha refactorizado el componente `HelloWorld`. Sigamos adelante y actualicemos el componente `App.vue` para usar la nueva sintaxis de TypeScript en Vue 3:

```
<script lang="ts">
import { defineComponent } from 'vue';
import HelloWorld from '@/components/HelloWorld.vue'

export default defineComponent({
  name: 'App',
  components: {
    HelloWorld
  },
});
</script>
```

Ejecutemos la aplicación usando el siguiente comando:

```
npm run serve
```

Wow, ¡Más errores y advertencias!

```
Argument of type 'typeof import(\"/.../vue-ts/
node_modules/vue/dist/vue\")' is not assignable to parameters of type 'PublicAPIComponent'.

Type 'typeof import(\"/.../vue-ts/node_modules/vue/dist/vue\")' is not 
assignable to type 'ComponentOptionsWithObjectProps<any, any, any, 
any, any, ComponentOptionsMixin, ComponentOptionsMixin, EmitsOptions, 
string, Readonly<{ [x: string]: any; }> | Readonly<...>>'.
...
```

**Importando los Components en Vue**

El error anterior se genera en la línea #2 en el archivo `main.ts`:

```
import { createApp } from 'vue';
import App from './App.vue'
       ^^^
createApp(App).mount('#app')
```

Typecript, como ES 6, soporta módulos mediante el uso de las palabras clave **import** y **export**. Siempre que estés escribiendo tus módulos en TypeScript, esto es, archivos que terminan con **.ts** , entonces estás cubierto.

El error anterior indica que TypeScript no puede importar el componente `App`, es como si TypeScript no entendiera lo que retorna el módulo `App.vue`.

¿Cuál es la solución? Definir un archivo de declaración(_declaration file_) en la carpeta raíz de la app. Este archivo tiene la extensión `.d.ts`. Básicamente, este archivo facilita que las herramientas sepan cómo manejar los archivos `*.vue`, también conocidos como _Single File Components_(SFC) o Componentes de Archivo Único.

Busca el archivo `shim-vue.d.ts` en la carpeta raíz de tu aplicación y reemplaza su contenido con lo siguiente:

```
declare module "*.vue" {
  import { defineComponent } from "vue";
  const component: ReturnType<typeof defineComponent>;
  export default component;
}
```

El código anterior declara un módulo TypeScript para cada archivo que termina en `*.vue` (SFC).

TypeScript procesa dicho módulo como si tuviera lo siguiente:

- Una declaración de _import_ para el método global `defineComponent`
- Declaración de una variable `component` de tipo `defineComponent`
- Finalmente, un _export_ predeterminado de la variable `component`

Teniendo el archivo de "corrección" anterior permite a TypeScript considerar cualquier componente de Vue como un módulo bien definido.

##### Ejecutar la aplicación

Ahora se puede ejecutar la aplicación de una forma segura sabiendo que correrá correctamente dentro del navegador.

Ejecute el siguiente comando para iniciar la aplicación:

```
npm run serve
```

Navega a la URL `http://localhost:8080` dentro de tu navegador y deberías poder ver la página de inicio predeterminada de una aplicación Vue 3 recién creada usando TypeScript, como se muestra en la **Figura 3** a continuación.

[![vue3-typescript-pagina-inicio](https://images.ctfassets.net/zojzzdop0fzx/1ocwf7c2QidwBZWVG3ktgQ/840662325b55c507d0a6b97cbfc1d55b/Screenshot_2020-08-11_at_10.23.14_PM.png)](https://images.ctfassets.net/zojzzdop0fzx/1ocwf7c2QidwBZWVG3ktgQ/840662325b55c507d0a6b97cbfc1d55b/Screenshot_2020-08-11_at_10.23.14_PM.png)

### Usando _Composition API_ con TypeScript

Ahora que la aplicación es compatible con TypeScript, permíteme mostrarte cómo puedes usar _Composition API_ y la seguridad de tipos para definir una función con parámetros tipados.

Reemplaza el contenido script del componente `HelloWorld` con lo siguiente:

```
import { defineComponent } from 'vue';

export default defineComponent({
  name: 'HelloWorld',
  props: {
    msg: {
      type: String,
      required: false,
    },
  },
  setup(props) {
    const printMsg = (msg: string) => console.log(`The message is: ${msg}`);

    return {
      printMsg,
    };
  },
});
```

Observa cómo el código anterior define una nueva función usando la API de composición con un parámetro tipado. El parámetro se llama `msg` y tiene un tipo de datos de cadena o `string`.

## Conclusión

Ya sea que estés actualizando tu aplicación Vue 2 existente o iniciando con una nueva, el artículo provee un enfoque paso a paso para agregar TypeScript a la aplicación actualizando al mismo tiempo a Vue 3, corrigiendo todas las advertencias y errores para finalmente levantar la aplicación con éxito en el navegador.

Este es tan sólo un paso en tu camino para crear aplicaciones Vue 3 con TypeScript. El siguiente paso será familiarizarse más con TypeScript.

* * *

Este artículo es una traducción al español de su [versión en inglés](https://labs.thisdot.co/blog/your-first-vue-3-app-using-typescript)