ianstormtaylor / slate

A completely customizable framework for building rich text editors. (Currently in beta.)
http://slatejs.org
MIT License
29.84k stars 3.25k forks source link

Typescript: PropsMerge type is invalid. #5490

Open NikitaIT opened 1 year ago

NikitaIT commented 1 year ago

https://github.com/ianstormtaylor/slate/blob/c8236ee112969fcab70ff4f159e1e4a18084ca6b/packages/slate/src/interfaces/transforms/node.ts#L85-L96

If we have only one key in props then real type is merge?: (prop: T["key"], node: T["key"]) => T["key"]

Example:

Transforms.setNodes(
                  editor,
                  {
                    key: { value: 1 },
                  },
                  {
                    at: ReactEditor.findPath(editor, leaf),
                    merge(prop: Leaf["key"], node: Leaf["key"]): Leaf["key"] {
                      assert(node.value === 1);
                      return node;
                    },
                  }
                );

Example2:

Transforms.setNodes(
                  editor,
                  {
                    key: "value",
                  },
                  {
                    at: ReactEditor.findPath(editor, leaf),
                    merge(prop: Leaf["key"], node: Leaf["key"]): Leaf["key"] {
                      assert(node === "value");
                      return node;
                    },
                  }
                );
skorenb commented 2 months ago

merge function has type PropsMerge which is defines as:

type PropsMerge = (prop: Partial<Node>, node: Partial<Node>) => object

As we see it expects objects but in setNodes usage of merge doesn't match the type as we pass values key by key: packages\slate\src\transforms-node\set-nodes.ts

          if (merge) {
            if (props[<keyof Node>k] != null)
              newProperties[<keyof Node>k] = merge(
                node[<keyof Node>k],
                props[<keyof Node>k]
              )
          }

Thus i guess PropsMerge type should expect key and appropriate values of descendant, similar to this:

type PropsMerge = <TValue extends Descendant[keyof Descendant]>(key: keyof Descendant, prop: TValue, node: TValue) => TValue

I have no idea how to implement this to get it working with typescript inferring