-
-
Notifications
You must be signed in to change notification settings - Fork 413
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Infer type of slots from $slots #539
Comments
Could you try does latest master branch support |
@johnsoncodehk import { VNodeProps, AllowedComponentProps, ComponentCustomProps, Slots as VueSlots } from 'vue';
type PublicProps = VNodeProps & AllowedComponentProps & ComponentCustomProps;
type GlobalComponentConstructor<Props = {}, Slots = VueSlots> = {
new (): {
$props: PublicProps & Props
$slots: Slots
}
}
interface QTreeSlots {
'default-header': (scope: { expanded: boolean, ticked: boolean, color: string }) => VNode[]
}
declare module "@vue/runtime-core" {
interface GlobalComponents {
QTree: GlobalComponentConstructor<QTreeProps, >
}
}
export declare type Slot = (...args: any[]) => VNode[];
declare type InternalSlots = {
[name: string]: Slot | undefined;
};
export declare type Slots = Readonly<InternalSlots>; So, a // Example usage in underlying code that renders the slot
const scope = {
expanded: true,
ticked: false,
color: 'green'
}
this.$slots['default-header'](scope)
// This shows the type of `$slots` and `Slots` is correct. So, the expected type of slot is: type SlotScope = { expanded: boolean, ticked: boolean, color: string } but it's currently like this: type SlotScope = (scope: { expanded: boolean, ticked: boolean, color: string }) => VNode[] This is the current code for inferring the type: function __VLS_getScriptSlots<T>(t: T): T extends new (...args: any) => { $slots?: infer S } ? (S extends object ? S : {}) : {};
// `Slot` is from 'vue'
function __VLS_getScriptSlots<T>(t: T): T extends new (...args: any) => { $slots?: infer S } ? (S extends Slot ? Parameters<S>[0] : {}) : {}; Edit: that won't work because it's for the whole object that contains all the slots. 🤦 |
* fix: Pick up the correct slot scope type from `$slots` See: #539 (comment) * fix: fixed slots type edge cases Co-authored-by: johnsoncodehk <[email protected]>
@yusufkandemir fixed, thank you. :) |
@johnsoncodehk well, thank you for the fix :) |
The current system analyzes the available slots in different ways and does a good job at that. However, this is not possible for external components(e.g. UI component libraries).
From vuejs/rfcs#192 (comment):
vuejs/core#4465 allows typing the slots, along with lots of other changes. So, after that gets merged,
$slots
will basically contain the typed slots.https://github.com/pikax/vue-next/blob/e201d2f046c46dc1fa26551ce28ac1a322ed1ad9/packages/runtime-core/src/componentPublicInstance.ts#L422
Volar is already inferring the props types from
$props
:https://github.com/johnsoncodehk/volar/blob/aa66f9fdc0b1752e58c56d680c942b9d2a3787ec/packages/vscode-vue-languageservice/src/utils/globalDoc.ts#L83-L90
So, in a similar way,
$slots
can be inferred too, then the current slot discovering system can do its job to enrich the types.Currently, the UI library/framework authors can ship the constructor types themselves, without depending on current Vue types. An example:
https://github.com/quasarframework/quasar/blob/76c0c841554751a5be743b0302523b63f956ba25/ui/types/ts-helpers.d.ts#L33-L37
(thanks for some imagination from #418 (comment) btw)
So, since this feature is not blocked by vuejs/core#4465 because there are currently ways to provide that type, I think this can be implemented right away! 🚀
The text was updated successfully, but these errors were encountered: