question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Property 'type' does not exist on type 'Node' when trying to apply custom formatting

See original GitHub issue

Description From the example (which isn’t in TS, but I am doing my best to translate as I follow along), using match seemed to work with custom types. This is my code for toggling Custom Formatting:

const [match] = Editor.nodes(editor, {
  match: (n: Node) => {
    return n.type === "code";
  },
});

However, I get the warning:

Property 'type' does not exist on type 'Node'.
  Property 'type' does not exist on type 'CustomText'

Recording Screen Shot 2022-03-25 at 3 25 26 AM

Environment

  • Slate Version:
"slate": "^0.76.0",
"slate-history": "^0.66.0",
"slate-react": "^0.76.0",
  • Operating System: macOS

  • TypeScript Version: "typescript": "^4.6.2"

Context I’ll add the relevant code below

declare module "slate" {
  interface CustomTypes {
    Editor: BaseEditor & ReactEditor;
    Element: CustomElement;
    Text: CustomText;
  }
}

type CustomText = { text: string };
type CustomElement =
  | { type: "paragraph"; children: CustomText[] }
  | { type: "code"; children: CustomText[] };

const RichEditor = (): ReactElement => {
  const editorRef = useRef<Editor>();

  if (!editorRef.current) {
    editorRef.current = withReact(withHistory(createEditor()));
  }
  const editor = editorRef.current;

  const initialValue: Descendant[] = [
    {
      type: "paragraph",
      children: [{ text: "A line of text in a paragraph." }],
    },
  ];

  const [value, setValue] = useState<Descendant[]>(initialValue);

  const customRenderer = useCallback((props) => {
    if (props.element.type === "paragraph") {
      return <Text {...props} />;
    } else if (props.element.type === "code") {
      return <Code {...props} />;
    }
  }, []);

  const formatCodeBlock = () => {
    const [match] = Editor.nodes(editor, {
      match: (n: Node) => {
        console.log(n);

        return n.type === "code";
      },
    });

    Transforms.setNodes(
      editor,
      { type: match ? "paragraph" : "code" },
      { match: (n) => Editor.isBlock(editor, n) }
    );
  };

  return (
    <Box>
      <Heading>Editor</Heading>
      <Box p={2} border="1px solid" borderColor="slate.100" rounded="md">
        <Box py={2}>
          <IconButton
            icon={<RiCodeLine />}
            onClick={formatCodeBlock}
            aria-label="sold"
            size="sm"
          />
        </Box>
        <Divider />
        <Slate
          editor={editor}
          value={value}
          onChange={(newValue) => setValue(newValue)}
        >
          <Editable renderElement={customRenderer} />
        </Slate>
      </Box>
    </Box>
  );
};

export default RichEditor;

Issue Analytics

  • State:open
  • Created a year ago
  • Reactions:5
  • Comments:10 (3 by maintainers)

github_iconTop GitHub Comments

9reactions
JoshuaKGoldbergcommented, Apr 25, 2022

I think you should find the answer here.

The type error still happens on the latest version, 0.77.2, even after using the Editor.isBlock or Element.isElement type predicates. BaseElement doesn’t have a type property.

TypeScript playground example:

import { BaseElement, Editor, Element, Node } from "slate";

declare const editor: Editor;
declare const node: Node;

if (Editor.isBlock(editor, node)) {
   node.type;
   //   ~~~~
   // Property 'type' does not exist on type 'BaseEditor | BaseElement'.
   //   Property 'type' does not exist on type 'BaseEditor'.
}

if (Element.isElement(node)) {
   node.type;
   //   ~~~~
   // Property 'type' does not exist on type 'BaseEditor | BaseElement'.
   //   Property 'type' does not exist on type 'BaseEditor'.
}

declare const baseElement: BaseElement;

baseElement.type;
//          ~~~~
// Property 'type' does not exist on type 'BaseElement'.
6reactions
dyakovkcommented, Jul 8, 2022

The next recommendation in the official documentation is not fully working https://docs.slatejs.org/concepts/12-typescript#migrating-from-0.47.x

You may occur with an error after narrowing types using Element.isElement(node)

Property 'type' does not exist on type 'BaseEditor | BaseElement'

To solve this you need to extend slate types like that

// custom.d.ts

import { BaseElement } from 'slate';

declare module 'slate' {
  export interface BaseElement {
    type: string;
  }
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

TypeScript - Slate
When referring to node.type , you may see the error Property 'type' does not exist on type 'Node' . To fix this, you...
Read more >
d3.js Property 'name' does not exist on type 'Node'
js, I get the data, structure as according to what I need and and then pass it as nodes but I get an...
Read more >
Google Visualization API Reference | Charts
Each column is assigned a data type, plus several optional properties including an ID, label, and pattern string. In addition, you can assign...
Read more >
Cell Renderer - Angular Data Grid
By default the grid will create the cell values using simple text. If you want more complex HTML inside the cells you can...
Read more >
typesafe-i18n - npm
FAQs · Installing typesafe-i18n fails · I added a new translation to my locale file, but TypeScript gives me the Error Property 'XYZ'...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found