type auto resolve when use defineExpose in typescript
What problem does this feature solve?
it seems that we must create type for a componet when use defineExpose
in typescript , and we can get type hint.
// src/types/index.ts
export type CompInst = {
getString: () => string;
};
// src/Comp.vue
<script setup lang="ts">
import { CompInst } from "./types";
defineExpose<CompInst>({
getString() {
return "hello";
},
});
</script>
<template>
<div>comp1</div>
</template>
// src/App.vue
<script setup lang="ts">
import Comp from "./Comp.vue";
import { CompInst } from "./types";
const compRef = ref<CompInst | null>(null);
// type hint !
compRef.value?.getString();
</script>
<template>
<Comp ref="compRef"></Comp>
</template>
maybe can we resolve type of expose by component directly?
What does the proposed API look like?
// src/App.vue
<script setup lang="ts">
// a inner tool can auto resolve expose type from type of component.
import { resolveExpose } from "vue"
import Comp from "./Comp.vue";
const compRef = ref<resolveExpose<typeof Comp> | null>(null);
// type hint !
compRef.value?.getString();
</script>
<template>
<Comp ref="compRef"></Comp>
</template>
maybe we can use InstanceType<typeof Comp>
to get instance type, but it expose many properties that we don't need.
You could use something like:
export type Constructor<Signature> = abstract new (...args: any) => Signature
// Remove default vue properties from the component ref instance
export type ComponentRef<Component extends Constructor<unknown>> = {
[
Key in keyof InstanceType<Component> as
// Remove vue builtins
Key extends `$${string}`
? never
// Remove custom directives
: Key extends `v${Capitalize<string>}`
? never
: Key
]: InstanceType<Component>[Key]
}
// usage
const compRef = ref<ComponentRef<typeof Comp> | null>(null);
That should leave you with much less noise by removing all of the vue related properties.
Be wary though, that it will still show all top-level properties, and non-exposed ones will not be available at runtime.