Skip to content
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

[Bug]: TypeError/regression introduced in 2.10.1: All options can be undefined #5859

Closed
1 task done
Mathias-S opened this issue Nov 22, 2024 · 4 comments
Closed
1 task done
Labels
Category: Open Source The issue or pull reuqest is related to the open source packages of Tiptap. Type: Bug The issue or pullrequest is related to a bug

Comments

@Mathias-S
Copy link
Contributor

Mathias-S commented Nov 22, 2024

Affected Packages

react, core, all extensions

Version(s)

2.10.1

Bug Description

Code that was previously working fine, now gives a TypeError when trying to access properties on this.options. These two examples were working fine in Tiptap 2.9, but now give errors:

Example 1

import Paragraph from "@tiptap/extension-paragraph";
import { mergeAttributes } from "@tiptap/react";

const MyStrangeParagraph = Paragraph.extend({
  renderHTML({ HTMLAttributes }) {
    return [
      `h1`,
      mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),
      //              ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 'undefined' is not assignable to 'Record<string, any>'
      0,
    ];
  },
});

Example 2

import Link, { type LinkOptions } from "@tiptap/extension-link";

interface MyLinkOptions extends LinkOptions {
  myFunc: () => void;
}

const MyLink = Link.extend<MyLinkOptions>({
  addCommands() {
    return {
      ...this.parent?.(),
      myNewCommand: () => () => {
        this.options.myFunc();
//      ^^^^^^^^^^^^^^^^^^^ Object possibly 'undefined'
      },
    };
  },
});

MyLink.configure({ myFunc: () => undefined });

Browser Used

Chrome

Code Example URL

No response

Expected Behavior

For example 1, I would expect this to work. I'm not sure how this can be done without using a non-null assertion this.options.HTMLAttributes! or without writing extra logic that wasn't previously necessary.

For example 2, I recognise that MyLink can be configured without passing in myFunc, so maybe the old code was wrong and there should always have been a nullish check such as this.options?.myFunc(). But shouldn't it be possible to provide mandatory options?

Additional Context (Optional)

Introduced with release 2.10.1 with #5854.

Also, I understand that the options types may be more correct now, but these changes are breaking type changes and according to Renovatebot, which we are using in our project, the passing percentage for this update is quite low, indicating there have been breaking changes. I don't know if this specific type change is the breaking change for everyone, but it is for us. See the below screenshot that shows Renovatebot stats for some of the packages.

image

Dependency Updates

  • Yes, I've updated all my dependencies.
@Mathias-S Mathias-S added Category: Open Source The issue or pull reuqest is related to the open source packages of Tiptap. Type: Bug The issue or pullrequest is related to a bug labels Nov 22, 2024
@nperez0111
Copy link
Contributor

Well that is a nifty package.

I am torn here because the type change introduced by 2.10 actually can prevent you from accessing something that does not exist (leading to a runtime error), and then there is this which is just forcing users to do checks for something that theoretically is accurate (someone may forget to call this.parent() in their addOptions). Not sure of an in-between on here.

@Mathias-S
Copy link
Contributor Author

Mathias-S commented Nov 22, 2024

What if mergeAttributes (and possibly other similar utilities that I'm not familiar with) would allow undefined in the type signature? The implementation already handles this just fine.

export function mergeAttributes(...objects: (Record<string, any> | undefined)[]): Record<string, any> {

Then the fix on our end would be trivial (just add optional chaining when accessing properties from this.options). Still a somewhat breaking change (type wise), but one that's much easier to handle. And arguably not really breaking since old implementations would have been incorrect.

But for other users there may be other cases where the type changes in 2.10 and 2.10.1 cause issues that I'm not aware of.

@nperez0111
Copy link
Contributor

I don't know that it really is easier. I've been trying to see if I can get a typing that works but it all very complicated with this pseudo inheritance. I think it is better to just revert both changes & leave the types alone. There will always be someone who complains about types

nperez0111 added a commit that referenced this issue Nov 22, 2024
* revert: "fix(core): update the typings to be that options and storage are partials on an extended config #5852 (#5854)"

This reverts commit 87d63d8.

* revert: "fix(core): update the typing of `addOptions`, `addStorage` to have an optional parent #5768 (#5770)"

This reverts commit d2f366d.
@nperez0111
Copy link
Contributor

This was released with 2.10.2

gethari pushed a commit to gethari/tiptap that referenced this issue Nov 23, 2024
…osis#5860)

* revert: "fix(core): update the typings to be that options and storage are partials on an extended config ueberdosis#5852 (ueberdosis#5854)"

This reverts commit 87d63d8.

* revert: "fix(core): update the typing of `addOptions`, `addStorage` to have an optional parent ueberdosis#5768 (ueberdosis#5770)"

This reverts commit d2f366d.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Category: Open Source The issue or pull reuqest is related to the open source packages of Tiptap. Type: Bug The issue or pullrequest is related to a bug
Projects
None yet
Development

No branches or pull requests

2 participants