I have this project that mostly uses jsx extensions despite being setup with typescript. When creating a new component, I decided to go with the tsx extension and ran into this error:
'AceEditor' cannot be used as a JSX component.
Its type 'typeof ReactAce' is not a valid JSX element type.
Types of construct signatures are incompatible.
Type 'new (props: IAceEditorProps) => ReactAce' is not assignable to type 'new (props: any, deprecatedLegacyContext?: any) => Component<any, any, any>'.
Construct signature return types 'ReactAce' and 'Component<any, any, any>' are incompatible.
The types returned by 'render()' are incompatible between these types.
Type 'Element' is not assignable to type 'ReactNode'.ts(2786)
I searched and found nothing and tried type assertion: as unknown as JSX.Element, but that didn’t work either.
My code:
import React from 'react';
import AceEditor from 'react-ace';
// Import necessary modes and themes from ace-builds
import 'ace-builds/src-noconflict/mode-javascript';
import 'ace-builds/src-noconflict/mode-python';
// Add more modes here as needed
import 'ace-builds/src-noconflict/theme-github'; // You can change the theme if you wish
import 'ace-builds/src-noconflict/theme-monokai'; // You can change the theme if you wish
interface CodeEditorProps {
language: string;
starterCode: string;
code: string;
onChange: (newValue: string) => void;
fontSize?: number; // Make fontSize an optional prop
}
const CodeEditorAce: React.FC<CodeEditorProps> = ({
language,
starterCode,
code,
onChange,
fontSize = 14,
}) => {
// Default fontSize is set to 14, but can be overridden by props
const getMode = (language: string) => {
switch (language.toLowerCase()) {
case 'javascript':
return 'javascript';
case 'python':
return 'python';
// Add more cases for other languages you support
default:
return 'text';
}
};
let value = code ? code : starterCode;
return (
<AceEditor
placeholder="Do not edit the starter code."
mode={getMode(language)}
theme="monokai"
value={value}
onChange={onChange}
name={`code-editor-${Math.random()}`} // Ensures a unique ID
editorProps={{ $blockScrolling: true }}
showPrintMargin={true}
showGutter={true}
highlightActiveLine={true}
setOptions={{
enableBasicAutocompletion: true,
enableLiveAutocompletion: true,
enableSnippets: true,
showLineNumbers: true,
tabSize: 2,
}}
fontSize={fontSize} // Set the font size here
height="100%"
width="100%"
/>
);
};
export default CodeEditorAce;
I also get the same issue if I use code mirror instead of Ace Editor:
'CodeMirror' cannot be used as a JSX component.
Its type 'ForwardRefExoticComponent<ReactCodeMirrorProps & RefAttributes<ReactCodeMirrorRef>>' is not a valid JSX element type.
Type 'ForwardRefExoticComponent<ReactCodeMirrorProps & RefAttributes<ReactCodeMirrorRef>>' is not assignable to type '(props: any, deprecatedLegacyContext?: any) => ReactNode'.
Type 'ReactElement<any, string | JSXElementConstructor<any>> | null' is not assignable to type 'ReactNode'.ts(2786)
"react": "^18.2.0",
"react-ace": "^10.1.0",
"ace-builds": "^1.32.7",
"react-dom": "^18.2.0",
I installed the types for ace and didn’t do much either.