How to fix ts check? #13992
-
|
type MessageProps = InstanceType<typeof Message>['$props']
export function message(options: MessageProps & { duration?: number }) {
...
const { duration=2, ...props} = options
const vnode = createVNode(Message, props)
render(vnode, el)
...
}
const msg = ref('Hello World!')
function onClick(){
message({duration: 1})
message({title: "title", duration: 2})
message({title: msg, duration: 3, class: "bg"})
} |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments
-
|
Use https://github.com/vuejs/language-tools/tree/master/packages/component-type-helpers. npm: vue-component-type-helpers import type { ComponentProps } from 'vue-component-type-helpers';
import MyComp from './MyComp.vue';
type MyCompProps = ComponentProps<typeof MyComp>; |
Beta Was this translation helpful? Give feedback.
-
|
Hello! The TypeScript error occurs because Solution 1: Unwrap Refs with import { createVNode, render, unref, type ComponentProps } from 'vue';
import Message from './Message.vue';
type MessageProps = ComponentProps<typeof Message>;
export function message(options: MessageProps & { duration?: number }) {
const { duration = 2, ...props } = options;
const staticProps = Object.fromEntries(
Object.entries(props).map(([key, value]) => [key, unref(value)])
);
const vnode = createVNode(Message, staticProps);
const el = document.createElement('div');
render(vnode, el);
}
const msg = ref('Hello World!');
function onClick() {
message({ duration: 1 });
message({ title: "title", duration: 2 });
message({ title: msg, duration: 3, class: "bg" });
}Solution 2: Type-Safe Props Extraction import { createVNode, render, unref, type ComponentProps } from 'vue';
import Message from './Message.vue';
type MessageProps = ComponentProps<typeof Message>;
type UnwrapProps<T> = {
[K in keyof T]: T[K] extends Ref<infer U> ? U : T[K];
};
export function message(options: UnwrapProps<MessageProps> & { duration?: number }) {
const { duration = 2, ...props } = options;
const vnode = createVNode(Message, props);
const el = document.createElement('div');
render(vnode, el);
}Solution 3: Runtime Type Guard export function message(options: MessageProps & { duration?: number }) {
const { duration = 2, ...props } = options;
const processedProps = {};
for (const [key, value] of Object.entries(props)) {
processedProps[key] = unref(value);
}
const vnode = createVNode(Message, processedProps);
const el = document.createElement('div');
render(vnode, el);
}Solution 4: Accept Both Static and Reactive Props import type { MaybeRef } from 'vue';
type MessageOptions = {
[K in keyof MessageProps]: MaybeRef<MessageProps[K]>;
} & { duration?: number };
export function message(options: MessageOptions) {
const { duration = 2, ...props } = options;
const staticProps = {};
for (const [key, value] of Object.entries(props)) {
staticProps[key] = unref(value);
}
const vnode = createVNode(Message, staticProps);
const el = document.createElement('div');
render(vnode, el);
}Recommended Approach: The key insight is that |
Beta Was this translation helpful? Give feedback.
-
|
Thanks for answer. My final solution is like this: export function message(options: MessageProps & { duration?: number }, children?: Record<string, () => VNodeChild>) {
// insert <Message .../>
}
function onClick(){
// <Message class="bg" :duration="3"><div>{ msg.value }</div></Messgae>
message({duration: 3, class: "bg"}, { default: () => <div>{ msg.value }</div> })
}Because I also found a [Vue wrarn] and it is not only ts issue. So I replace ref-prop with slot. It works and has no warning. |
Beta Was this translation helpful? Give feedback.
Thanks for answer.
My final solution is like this:
Because I also found a [Vue wrarn] and it is not only ts issue. So I replace ref-prop with slot. It works and has no warning.