slate: Property 'type' does not exist on type 'Node' when trying to apply custom formatting
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

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;
About this issue
- Original URL
- State: open
- Created 2 years ago
- Reactions: 9
- Comments: 16 (3 by maintainers)
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.isBlockorElement.isElementtype predicates.BaseElementdoesn’t have atypeproperty.TypeScript playground example:
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)To solve this you need to extend slate types like that
Quick workaround: Change:
to
For this problem, the solution is simple and actually documented in official docs
You need to check if node is block like this:
@rahulnyk you need to narrow down the type of the Node to Element. You can do that by applying a condition, either an
ifor by already suggested simple conjunction, e.g.:or
The second example might fail if your custom
Elementtype doesn’t have thetypeproperty. The first one should work 100 %.Thanks for the help.
Mine was actually for bold. I found a workaround for this by first extending the BaseEditor and then creating a new type for Text and Element.