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.isBlock
orElement.isElement
type predicates.BaseElement
doesn’t have atype
property.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
if
or by already suggested simple conjunction, e.g.:or
The second example might fail if your custom
Element
type doesn’t have thetype
property. 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.