Closed xiaweiss closed 2 months ago
Already reported https://github.com/ueberdosis/tiptap/issues/5632
You do have to use new
and your Component type is probably incorrect, but it is hard to see with just a screenshot
Thank you, the code in screenshot works fine, it just has the typescript error, I can ignore it for now by adding // @ts-ignore
This is still an issue for me with version 2.8.0 using examples from the website
This is the syntax-highlighting example from here: https://tiptap.dev/docs/examples/advanced/syntax-highlighting
and this component is simply being imported and passed to VueNodeViewRenderer and throwing the same type error as mentioned above. Using new should not be required and would only throw a different error.
<template>
<NodeViewWrapper class="code-block">
<select contenteditable="false" v-model="selectedLanguage">
<option :value="null">auto</option>
<option disabled>—</option>
<option v-for="(language, index) in languages" :value="language" :key="index">
{{ language }}
</option>
</select>
<pre><code><NodeViewContent /></code></pre>
</NodeViewWrapper>
</template>
<script>
import { NodeViewContent, nodeViewProps, NodeViewWrapper } from '@tiptap/vue-3'
export default {
components: {
NodeViewWrapper,
NodeViewContent
},
props: nodeViewProps,
data() {
return {
languages: this.extension.options.lowlight.listLanguages()
}
},
computed: {
selectedLanguage: {
get() {
return this.node.attrs.language
},
set(language) {
this.updateAttributes({ language })
}
}
}
}
</script>
Here is where the CodeBlockComponent is being passed to VueNodeViewRenderer which throws the type error.
I am temporarily using "as" to cast the type to Component
CodeBlockLowlight
.extend({
addNodeView() {
return VueNodeViewRenderer(CodeBlockComponent)
},
})
.configure({ lowlight })
You are right about not needing the new
but it is not clear what the error is then. Can you share the full error?
I'd take a PR contribution here, ts types aren't very high priority
Here is the full error, my current understanding and solution.
Argument of type:
DefineComponent<
{
editor: { type: PropType<Editor>; required: true };
node: { type: PropType<Node>; required: true };
decorations: {
type: PropType<readonly DecorationWithType[]>;
required: true;
};
/* 4 more */;
deleteNode: { ...; };
},
/* 11 more */,
{}
>
is not assignable to parameter of type
Component<NodeViewProps>
Type:
DefineComponent<
{
editor: { type: PropType<Editor>; required: true };
node: { type: PropType<Node>; required: true };
decorations: {
type: PropType<readonly DecorationWithType[]>;
required: true;
};
/* 4 more */;
deleteNode: { ...; };
},
/* 11 more */,
{}
>
is not assignable to type:
ComponentPublicInstanceConstructor<
NodeViewProps,
any,
any,
any,
ComputedOptions,
MethodOptions
>
Type:
CreateComponentPublicInstance<
Readonly<
ExtractPropTypes<{
editor: { type: PropType<Editor>; required: true };
node: { type: PropType<Node>; required: true };
decorations: {
type: PropType<readonly DecorationWithType[]>;
required: true;
};
/* 4 more */;
deleteNode: { ...; };
}>
>,
/* 18 more */,
{}
>
is missing the following properties from type
NodeViewProps
• view • innerDecorations • HTMLAttributes
It could be that it's more of an issue with the documentation and that Typescript just struggles to infer the necessary types correctly but the Tiptap documents insinuate that passing nodeViewProps
is enough to make it compatible with Typescript.
The issue is that nodeViewProps
is not of the type NodeViewProps
that is expected by VueNodeViewRenderer
It is missing HTMLAttributes
, view,
and innerDecorations
properties or at least Typescript is not able to infer them.
Using defineComponent
with the options API is not enough to make the type inference work. However, using defineComponent
with setup works as expected so that's what I am doing now.
Use this
return VueNodeViewRenderer(
defineComponent({
props: nodeViewProps,
setup(props) {
return () => h(TiptapCodeBlock, props)
}
})
)
instead of simply doing this
return VueNodeViewRenderer(TiptapCodeBlock)
There are a few cases where I use the component outside of the editor as well, in those cases, I wrap the component in NodeViewWrapper
and use NodeViewContent
using h
directly within defineComponent
.
component, contenteditable, contentAs are dynamic in my case below. I am just sharing this incase it helps anyone else out.
VueNodeViewRenderer(
defineComponent({
props: nodeViewProps,
setup(props) {
return () =>
h(NodeViewWrapper, { contenteditable }, [
h(component, props.node.attrs, {
default: () => h(NodeViewContent, { ...(contentAs ? { as: contentAs } : {}) })
})
])
}
})
)
Affected Packages
core, vue
Version(s)
Bug Description
Browser Used
Chrome
Code Example URL
No response
Expected Behavior
Type is correct
Additional Context (Optional)
No response
Dependency Updates