suren-atoyan / monaco-react

Monaco Editor for React - use the monaco-editor in any React application without needing to use webpack (or rollup/parcel/etc) configuration files / plugins
https://monaco-react.surenatoyan.com/
MIT License
3.81k stars 268 forks source link

Typescript Interfaces: Type annotations can only be used while typeScript configuration setup. #640

Open Malnasser opened 3 months ago

Malnasser commented 3 months ago

Describe the bug I'm working on a project to run react directly from the browser. I configured everything for Typescript as showing below in the code snippet. But Monaco still seems that I'm running javascripts for some reasons.

Steps to reproduce the behavior:

  1. add this component to your code:
    
    import Editor from '@monaco-editor/react';
    import { useRef } from 'react';

type Props = { value: string; onChange: (code: string) => void; };

export default function CodeEditor({ value, onChange }: Props) {

const editorRef = useRef(null);

function handleEditorDidMount(editor: any, monaco: any) { monaco.languages.typescript.typescriptDefaults.setCompilerOptions({ target: monaco.languages.typescript.ScriptTarget.ES2016, allowNonTsExtensions: true, moduleResolution: monaco.languages.typescript.ModuleResolutionKind.NodeJs, module: monaco.languages.typescript.ModuleKind.CommonJS, noEmit: true, typeRoots: ["node_modules/@types"], jsx: monaco.languages.typescript.JsxEmit.React, jsxFactory: 'React.createElement', jsxFragmentFactory: 'React.Fragment', allowJs: true, });

editorRef.current = editor;

}

return ( <Editor theme="vs-dark" height="90vh" defaultLanguage="typescript" defaultValue={value} onMount={handleEditorDidMount} /> ); }

3. then type this react component into Monaco UI.
```ts
import {
  Body,
  Button,
  Container,
  Head,
  Heading,
  Hr,
  Html,
  Img,
  Link,
  Preview,
  Section,
  Text,
} from "@react-email/components";
import * as React from "react";

interface LinearLoginCodeEmailProps {
  validationCode?: string;
}

const baseUrl = "https://react-email-demo-9fn3mchcm-resend.vercel.app"

export const LinearLoginCodeEmail = ({
  validationCode = "tt226-5398x",
}: LinearLoginCodeEmailProps) => (
  <Html>
    <Head />
    <Preview>Your login code for Linear</Preview>
    <Body style={main}>
      <Container style={container}>
        <Img
          src={`${baseUrl}/static/linear-logo.png`}
          width="42"
          height="42"
          alt="Linear"
          style={logo}
        />
        <Heading style={heading}>Your login code for Linear</Heading>
        <Section style={buttonContainer}>
          <Button style={button} href="https://linear.app">
            Login to Linear
          </Button>
        </Section>
        <Text style={paragraph}>
          This link and code will only be valid for the next 5 minutes. If the
          link does not work, you can use the login verification code directly:
        </Text>
        <code style={code}>{validationCode}</code>
        <Hr style={hr} />
        <Link href="https://linear.app" style={reportLink}>
          Linear
        </Link>
      </Container>
    </Body>
  </Html>
);

LinearLoginCodeEmail.PreviewProps = {
  validationCode: "tt226-5398x",
} as LinearLoginCodeEmailProps;

export default LinearLoginCodeEmail;

const logo = {
  borderRadius: 21,
  width: 42,
  height: 42,
};

const main = {
  backgroundColor: "#ffffff",
  fontFamily:
    '-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif',
};

const container = {
  margin: "0 auto",
  padding: "20px 0 48px",
  maxWidth: "560px",
};

const heading = {
  fontSize: "24px",
  letterSpacing: "-0.5px",
  lineHeight: "1.3",
  fontWeight: "400",
  color: "#484848",
  padding: "17px 0 0",
};

const paragraph = {
  margin: "0 0 15px",
  fontSize: "15px",
  lineHeight: "1.4",
  color: "#3c4149",
};

const buttonContainer = {
  padding: "27px 0 27px",
};

const button = {
  backgroundColor: "#5e6ad2",
  borderRadius: "3px",
  fontWeight: "600",
  color: "#fff",
  fontSize: "15px",
  textDecoration: "none",
  textAlign: "center" as const,
  display: "block",
  padding: "11px 23px",
};

const reportLink = {
  fontSize: "14px",
  color: "#b4becc",
};

const hr = {
  borderColor: "#dfe1e4",
  margin: "42px 0 26px",
};

const code = {
  fontFamily: "monospace",
  fontWeight: "700",
  padding: "1px 4px",
  backgroundColor: "#dfe1e4",
  letterSpacing: "-0.3px",
  fontSize: "21px",
  borderRadius: "4px",
  color: "#3c4149",
};
  1. Monaco would complain about interfaces and type annotations Type annotations can only be used in TypeScript files. similar syntax error would be shown if you add the code into .jsx file in vs code.

Expected behavior Expected behavior that Monaco should treat the file like it's .tsx not tsx since selected language is typescript

Screenshots If applicable, add screenshots to help to explain your problem.

Screenshot 2024-08-10 at 8 14 19 PM

suren-atoyan commented 3 months ago

There is no full support of JSX/TSX out of the box. Check this issue (particularly this comment might be helpful). Also, remove allowJs: true for interfaces to be recognized.