What is the method for extracting a Vue instance from `defineComponent()` in Vue 3?

In Vue 3, it is now possible to write components in TypeScript:

/// modal.vue

<template>
  <div class="modal"></div>
</template>

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

export default defineComponent({
  name: "Modal",
  props: {
    foo: String,
    bar: String
  },
  mounted() {
    this.$props.foo // how to type `this` out of this context?
  }
});
</script>

I am curious about how to properly type the vue instance outside of the defineComponent function?

/// another ts file.
let modal:???; // what should be used in place of `???`?

modal.$props.foo // make correct inference for `$props.foo`

Answer №1

Learn how to leverage the InstanceType utility in TypeScript for extracting instance types

import Modal from './modal.vue'

type ModalInstance = InstanceType<typeof Modal>

type Foo = ModalInstance['$props']['foo']

https://i.sstatic.net/LC97S.png

Take a look at another example using a utility type:

import { AllowedComponentProps, Component, defineComponent, VNodeProps } from 'vue'

export type ExtractComponentProps<TComponent> =
  TComponent extends new () => {
    $props: infer P;
  }
    ? Omit<P, keyof VNodeProps | keyof AllowedComponentProps>
    : never;
  
const TestComponent = defineComponent({
  props: {
    disabled: {
      type: Boolean,
    },
  },
});
  
type Props = ExtractComponentProps<typeof TestComponent>

// type Props = {
//   disabled?: boolean | undefined;
// }

Answer №2

The solution I initially thought of was to use

ReturnType<typeof defineComponent>
, but it lacked the necessary type information. Delving into how ReturnType could work with a generic method led me down a Stack Overflow rabbit hole that intrigued me.

Upon further investigation, I discovered that Vue offers an exported type called ComponentPublicInstance which can be easily utilized. This ComponentPublicInstance also has various generic parameters.

import { ComponentPublicInstance } from 'vue';

let instance: ComponentPublicInstance<{ prop: string }, { value: string }>;

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

Enforcing alias types in TypeScript arguments is necessary for maintaining consistency and clarity

I'm currently facing a challenge with type unions and aliases. I have an alias for values that can possibly be null or undefined, along with a function that handles these values. Everything is running smoothly and safely. However, there are instances ...

Attempting to assign various arrays based on a specific value but encountering an issue: it seems there may be an infinite update loop within the component's render function

As I attempt to assign different values to this array based on another variable, I encounter an error [Vue warn]: You may have an infinite update loop in a component render function. I initialize the array as empty in the data() section of the Vue file ...

Encountering a Typescript error while attempting to convert a JavaScript file to Typescript within an Express

After deciding to transition my express.js code to typescript, I have encountered an issue with my user model. Below is a simplified version of the code: //user.model.ts import { Schema, Types } from 'mongoose'; export interface User { na ...

How can I display the values stored in an array of objects in Angular 2

I need help printing out the value of id from an array that is structured like this: locations = [ {id: '1', lat: 51.5239935252832, lng: 5.137663903579778, content: 'Kids Jungalow (5p)'}, {id: '2', lat: 51.523 ...

How can we efficiently determine if any of the keys in an array of objects contains a value that is present in another array of arrays object?

I am working on developing a filtering system that checks for the existence of project technologies in the arrOfObjs.name. If a match is found, then the filter will allow the project to be displayed in the DOM. This filter specifically involves using a com ...

Array objects will be filtered based on a separate array within the data

In my current database query, I am retrieving an array of 20 objects that each have a unique id assigned to them. Additionally, I have a separate array containing 2 specific ids. My goal is to filter out and retrieve only those 2 objects from the initial ...

Finding the ID of the element that was clicked with strict typing

Consider a scenario where we aim to record the ID attribute of a clicked element using the TypeScript code snippet below: onClick(event) { console.log(event.target.attributes.id.nodeValue); } The function above takes the clicked object as an argument, h ...

Styling Components with MUI and Harnessing the Power of TypeScript

I'm encountering an issue with the following code snippets import {Button,ButtonProps} from '@mui/material'; import { alpha, styled } from '@mui/material/styles'; import { Link as RouterLink } from 'react-router-dom'; co ...

Inheritance within classes is ineffective

Currently facing an issue with building an Icon component that should inherit properties from a base class. Strangely, upon instantiation of the Icon, none of the properties from super are present, and the __proto__ property is not properly set. Despite r ...

Encountering a discord bot malfunction while on my Ubuntu server

My discord bot runs smoothly on my Windows 10 setup, but when deployed to the server running Ubuntu Server 20, it encounters a specific error. The issue arises when trying to handle incoming chat messages from the server. While I can read and respond to m ...

Error message indicating absence of content on faraway server while utilizing Axios baseURL feature

After deploying my app to a remote server, I encountered an issue where the app appears blank or empty, even though it works perfectly when running locally with the same static site build. Interestingly, the app functions properly on the remote server if I ...

Generate an array with an extra attribute included

When working with a third-party API that requires passing an array with an additional property, things can get a bit tricky. The standard approach involves creating a type like this: type SomeArgument = string[] & { foo: string }; doSomething(argument ...

Changing the Redux state within a custom hook will not trigger a re-render

I recently created a custom wrapper-hook for a Redux slice to avoid using the "{ type: x, payload: y }" syntax :p) Below is the code for the slice: // polycanvas.ts (Redux) export const polycanvas = createSlice({ name: 'polycanvas', initial ...

Using angular2-google-maps in conjunction with an Angular2 application

I have successfully integrated the angular2-google-map with my angular2 application. Below is the content of app.module.ts file: import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; ...

Should I choose JavaScript or TypeScript for Angular 2.0?

What is the best approach for creating an Angular 2.0 application? Should it be done with JavaScript or TypeScript? I'm struggling to get started with Angular 2.0 using TypeScript, as it's quite different from JavaScript. ...

Apologies, but the module '@vue/babel-preset-app' could not be located

After creating a new Vue application, I encounter an error when running the server and the compilation fails. Can anyone help me identify the source of this issue? Below are screenshots of my Terminal and browser. The main.js file import Vue from ' ...

Ways to resolve the issue of incompatible parameters 'action' types in JavaScript

I'm encountering a common problem, but I can't figure out why this error is happening. After updating redux, I encountered the following error message: TS2322: Type '(state: ILanguage | undefined, action: PayloadAction<ILanguage>) =&g ...

Testing React Hook Form always returns false for the "isValid" property

When creating a registration modal screen, I encountered an issue with the isValid value when submitting the form. In my local environment (launched by npm start), the isValid value functions correctly without any issues. However, during unit testing us ...

Connecting Multiple Relationships with Many-To-Many Matches

My database consists of the following entities: @Entity class User { @ManyToMany(type => Group) @JoinTable() groups: Group[]; } @Entity class MediaObject { @ManyToMany(type => Group) @JoinTable() groups: Group[]; } @Entity ...

Tips for postponing 'not found' error until the data has finished loading in Vue.js

I am accessing the following route: http://site.dev/person/1 The structure of my component is as follows: // PeopleComponent.vue <template> <div> <template v-if="person == null"> <b>Error, person does not exist.</b& ...