Search code examples
typescriptvue.jstiptap

How to add a custom extension when using typescript


I am trying to add a custom extension to scrumpy/tiptap, but my project is using typescript and I think this is causing me some problems.

I got the code from this issue, and tried importing and using it like this:

import HighlightMark from '../ts/tiptap-extensions/HighlightMark';

...

this.editor = new Editor({
  content: '<p>This is just a boring paragraph.</p>',
  extensions: [new HighlightMark()]
})

But I am faced with this error

Type 'HighlightMark' is not assignable to type 'ExtensionOption'. Type 'HighlightMark' is not assignable to type 'Mark'. The types returned by 'schema.toDOM(...)' are incompatible between these types. Type '(string | number | { style: string; })[]' is not assignable to type 'DOMOutputSpec'. Property '0' is missing in type '(string | number | { style: string; })[]' but required in type 'DOMOutputSpecArray'.


I tried importing it in a .d.ts (as I had to do with all the built-int tiptap extensions), but I get an error telling me that I can't import files from relative path here:

Import or export declaration in an ambient module declaration cannot reference module through relative module name.ts(2439)


I also tried just changing the file to typescript (HighlightMark.ts), but it then gives me several errors:

Property 'commands' in type 'HighlightMark' is not assignable to the same property in base type 'Mark'. Type '({ type }: { type: any; }) => (attrs: any) => Command' is not assignable to type '({ type, schema, attrs }: { type: MarkType; schema: MarkSpec; attrs: { [key: string]: string; }; }) => CommandGetter'. Type '(attrs: any) => Command' is not assignable to type 'CommandGetter'.

and

'mark' is declared but its value is never read.ts(6133) Parameter 'mark' implicitly has an 'any' type.ts(7006)

and

Parameter 'attrs' implicitly has an 'any' type.ts(7006)

Has anyone done this before? Is it actually possible?

This is the code from HighlightMark.js:

   import { Mark } from 'tiptap';
   import { toggleMark } from 'tiptap-commands'

  export default class HighlightMark extends Mark {
  get name() {
    return "mark";
  }

  get schema() {
    return {
      attrs: {
        color: {
          default: "rgba(240,87,100,0.7)"
        }
      },
      parseDOM: [
        {
          tag: "mark"
        }
      ],
      toDOM: mark => [
        "mark",
        {
          style: `background: red` // ${mark.attrs.color}
        },
        0
      ]
    };
  }

  commands({ type }) {
    return attrs => toggleMark(type, attrs);
  }
}

Solution

  • It seems I could resolve this by initialising tiptap like this

    this.editor = new Editor({
      content: '<p>This is just a boring paragraph.</p>',
      extensions: [new HighlightMark() as any]
    

    Which is not ideal, but seems to be working for now.

    If anyone can post the real solution I will mark it as the answer