Generating statically typed events in Vue

Recently, I encountered a run-time error in a Vue / Typescript application due to the lack of typing for custom events.

For example, the following code compiles without any issues but fails at run-time:

  // Within component A
  public foo() {
    this.$emit("connect", { username: this.username, password: this.password });
  }
// Component B
<template>
  ... <ComponentA @connect="onConnect"> ...
</template>
<script lang="ts"&quo;
...
  public onConnect(username: string, password: string) {
  ...

Is there a way to avoid such errors during compile time? I am looking for a solution where the emitter and receiver types are linked, so I can catch any mismatches at compile time rather than at run-time.

Edit: I am not seeking a fix for the above error.

Edit: Just to clarify, the main issue is the mismatch between the type passed to emit and the type expected by the callback, which is not caught during compile time.

Answer №1

One possible solution is to utilize the vue-typed-emit library.

Answer №2

If you want to enhance the functionality of your data interface, make sure to always encapsulate the emitter and only invoke your custom foo method to abstract the this.$emit call:

models/User.ts

export interface User {
  name: string
  password: string
}

ComponentA.vue

import { User } from '@/models/User';
...
public foo(user: User) {
  this.$emit("connect", user);
}

ComponentB.vue

import { User } from '@/models/User';
...
public onConnect(user: User) {
  ...

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Global Vue Component Styles Seeping Through Entire Website Interface

By "Leaking", I mean the following scenario. I have an About.vue file with its own styling (About.scss) and endpoint "/about". Additionally, I have the home page endpoint "/" and its corresponding Laravel blade template (Index.blade.php) with its own styli ...

Modify the dynamic style of an Angular input field

Looking for assistance with a text box <input type="text" [ngStyle]="(show_div===true) ? {'border-color':'red','color':'red'} : {'border-color': 'green','color':'g ...

Testing NextJS App Router API routes with Jest: A comprehensive guide

Looking to test a basic API route: File ./src/app/api/name import { NextResponse } from 'next/server'; export async function GET() { const name = process.env.NAME; return NextResponse.json({ name, }); } Attempting to test ...

Vue-Router does not currently have built-in support for the dynamic import() function

Encountering an issue with the code below indicating "unexpected token import": const Router = new VueRouter({ routes: [ { path: '', component: () => import('pages/landing/landing') } ] }) A solution that is currently ...

Having trouble retrieving an object property in HTML or TypeScript within an Angular framework?

export class ComponentOne { array_all_items: Array<{ page_details: any }> = []; array_page_details: Array<{ identifier: number, title: string }> = []; initial_item: Array<{ identifier: number, title: string }> = [ { ...

Utilize the composite primary key of an Entity within Typeorm for efficient data retrieval

I am working with the following database entities: @Entity() class Team { @PrimaryGeneratedColumn() id: string @PrimaryColumn() teamName: string @OneToMany(() => Player, player => player.team) players: Player[] } @Entity() class Player ...

What is the best way to distinguish between a button click and a li click within the same li element

In my angular and css GUI, each line is represented as an li inside a ul with a span. The functionality includes a pop-up opening when clicking on the li background and another action occurring when pressing the button (as intended). The issue arises when ...

Nuxt3 - Issue with Accessing Environmental Variable in Pinia Store

I've encountered an issue while trying to access the BASE_URL from the environment in a Pinia store within Nuxt using runtimeConfig, resulting in a 500 Nuxt instance unavailable error. Below is the error image link: https://i.sstatic.net/hOZF7.png ...

I believe this solution is functional, but it seems to undermine the intention of utilizing a framework

Having just started with vue and js, I recently put together a photo gallery. I'm looking to reduce the opacity of selected photos and then reset it when switching between photos. The current code works fine, but I believe there could be a better way ...

How can I prevent the enter key from working with Twitter Typeahead?

Is there a way to prevent the enter key from being pressed on an element within Twitter Typeahead's dropdown feature while using Angular with Typescript? I attempted to utilize preventDefault() when event.keycode === 13 on the ng-keydown event for th ...

Sorting an object array by date is causing a problem

UPDATE: Finally cracked the code on this issue. I initially assumed that Date was interpreting the date ("29-04-2020") as DD-MM-YYYY, when it should actually be MM-DD-YYYY. For instance, here's an object array I'm working with: let t ...

Module '@types/mongodb' could not be located

Currently, I am working on a Node.js application using Typescript with a MongoDb database. Unfortunately, I encountered an issue today related to importing the type definitions of MongoDb. When I try to import the Db type like this: import { Db } from "@ ...

Check if a Vue 3 component has been loaded and if not, load a general component

Currently in the process of migrating a project from Vue 2 to Vue 3, I find myself searching for a way to determine if a component is loaded, and if not, how to load a GenericComponent as a placeholder. In Vue 2, I was able to accomplish this task using ...

Troubleshooting Angular4 and TypeScript Compile Error TS2453: A Comprehensive

I'm facing an issue in my Angular4 project build process which I find quite perplexing. The error seems to be related to the import of certain components such as Response, Headers, and Http from @angular. Whenever I attempt to build my project, it thr ...

Getting files from CDN using NuxtJS content module - a beginner's guide

Is there a way to fetch files from an external server, such as a CDN, using the @nuxtjs/content module? This would allow me to manage the .md files independently without relying on Nuxt.js. In my current nuxt.config.js file, I have the following setup: ex ...

The speed of the OpenLayers web application is significantly hindered when accessed from a mobile device using Android

Although it may seem like a common question that should be closed, I have reached a roadblock and cannot find a solution. I hope to provide enough details to make this question suitable for SO. I am currently working on an OpenLayers web application that ...

Incompatibility issues between NestJS and socket.io package

After diligently following the documentation, I attempted to install and work with socket.io on nestjs. However, I encountered multiple issues when installing packages. Despite trying different methods to update the package, nothing seemed to resolve the i ...

Utilizing Next.js App Router to Enable Static Site Generation for Dynamic Routes in Live Environments

For my portfolio, I am utilizing Next.js's new App Router to highlight projects with dynamic routing (src/app/projects/[id]/page.tsx). During development, useSearchParams is able to correctly retrieve the project ID. However, in production, it returns ...

Issue with grid breakpoints for medium-sized columns and grid rows not functioning as expected

I'm working on building a grid layout from scratch in Vue.js and have created my own component for it. In my gridCol.vue component, I have defined several props that are passed in App.vue. I'm struggling to set up breakpoints for different screen ...

Is there a way for me to insert a variable into the src attribute of my img tag like this: `<img alt="Avatar" src=`https://graph.facebook.com/${snAvatarSnuid}/picture`>`

I need assistance with passing a variable called snAvatarSnuid within the img src tag, specifically after facebook.com/ and before /picture as shown below: <img alt="Avatar" src=`https://graph.facebook.com/${snAvatarSnuid}/picture`> Note: 1) The ht ...