After delving into this topic further, here are my discoveries 1, 2:
Within Vue2, it was possible to craft a universal function that would yield a component definition:
const generateUniversalSearch<T>() {
return defineComponent({
props: {
options: {
type: Array as PropType<T[]>,
default: () => []
},
labelKey: {
type: String as PropType<keyof T>,
default: 'label'
}
},
// ...
})
}
...and then utilize it in the parent component like so:
import { generateUniversalSearch } './path/to/it'
export default defineComponent({
components: {
MyCustomSearch: createGenericSearch<MyCustomItemType>()
}
})
However, while effective, this approach has a significant downside: it deviates from using Single File Components for <GenericSearch />
. Consequently, you must pass the template as a prop of defineComponent
and relocate all <style />
content to the parent component.
The main drawback of abandoning the SFC pattern is that Vue must now compile the template at runtime, necessitating the use of the compiler-inclusive Vue version – resulting in an increase of over 200k
. While I advocate for Typescript, enlarging your app size significantly outweighs TS's lack of awareness regarding labelKey
being keyof OptionType
in my generalized typed search component.
Note that employing generic types through the Class API is still feasible, but due to its deprecated status, I won't delve into it here.
In Vue3, the incorporation of generic types has been simplified with
<script setup lang="ts" generic="T">
defineProps<{
options: T[]
labelKey: keyof T
}>()
</scipt>
, introduced in version 3.3
.
For more information, refer to the official documentation and this answer.
1 - Although labeled under vue3.js, the project currently operates on
<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d0a6a5b590e2fee7">[email protected]</a>
, gearing up for migration to
vue@3
. The ongoing transition involves shifting components from Options API to Composition and implementing minor typescript enhancements. At the time of posting this query, I was unaware of Vue's support for generics and the distinct syntax between versions
^2
and
^3
.
2 - During my exploration on creating a generically-typed component, I discovered this informative article.