Reputation: 7338
As you know, as of Vue 3, component could be written 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>
My question is how can I type the vue instance out of the defineComponent
function?
/// another ts file.
let modal:???; // what the `???` should be?
modal.$props.foo // infer `$props.foo` correctly
Upvotes: 11
Views: 11506
Reputation: 13434
Use the TypeScript's built-in InstanceType
utility to extract its instance type
import Modal from './modal.vue'
type ModalInstance = InstanceType<typeof Modal>
type Foo = ModalInstance['$props']['foo']
Another one 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;
// }
Upvotes: 10
Reputation: 1419
The "simple" answer I was going to give was to use ReturnType<typeof defineComponent>
however that doesn't carry any of the type information. As I started to look at how ReturnType
could be used with a generic method I fell down stackoverflow rabbit hole where these seemed like something to explore
However after looking at it, vue has an exported type ComponentPublicInstance
that can be used fairly easily. ComponentPublicInstance
also has handful of different generic parameters.
import { ComponentPublicInstance } from 'vue';
let instance: ComponentPublicInstance<{ prop: string }, { value: string }>;
Upvotes: 9