microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
100.1k stars 12.37k forks source link

TypeScript support for .mdx file extensions #36440

Open PaulieScanlon opened 4 years ago

PaulieScanlon commented 4 years ago

Search Terms

Suggestion

Could or would it be on the road map to allow type checking in non .ts files. In my case i'm specifically wondering if TypeScript can type check React components in .mdx files

Use Cases

I've written a gatsby plugin gatsby-mdx-embed that allows users to embed media content from YouTube, Twitter, Instagram etc in their .mdx files.

The plugin is written in TypeScript and all of the components have props. It would be sweet if when these components are used in .mdx files a user could either see the prop types by hovering over the component or more importantly would get a type error (squiggly line) in their code editor if the prop name is incorrect or of incorrect type.

Examples

Here's an example .mdx file

You can below there the Gist component accepts a gistLink prop of type string.

<Playground>
  <Gist gistLink="PaulieScanlon/ca0cc9239176066492cb2aba435edbf7" />
</Playground>

If a user misspelled gistLink or provided a number / array or object etc the editor would alert them there's been an error in the prop type used.

Peeja commented 4 years ago

Similarly, when writing Storybook stories in MDX, it would be a big help to have TypeScript understand them. Stories are a kind of test, and not type-checking tests is a scary prospect.

donaldpipowitch commented 4 years ago

As others already said .mdx currently gets a lot of traction - especially in the Gatsby and Storybook community. To chime in with something useful in the discussion here some download stats for @mdx-js/mdx.

image

I'd love to see .mdx support in TypeScript (as long as it isn't possible to add such a feature in community land via "plugins").

Another argument which wasn't mentioned yet as far as I know for not creating a standalone "MDX Language Server": .mdx files can be dropped into any existing TypeScript project. You can't just import other TypeScript files into your .mdx file - it also works the other way around. .mdx files can export things as well. At the end it is just a JavaScript/TypeScript file with a different syntax - not much different to the JSX support TypeScript offers.

nicmosc commented 3 years ago

Any news on this? Currently building a component library in TS and writing the documentation with MDX. As you can imagine it's a pain right now using those components without any hints about the props, which are easily available in any .tsx file, but non-existant in .mdx

maxammann commented 3 years ago

I think this could be achieved with https://github.com/microsoft/TypeScript/issues/16607 So this is definitely blocked by this issue. I think it does not make sense to integrate this into the core typescript library. What do you think?

sarahdayan commented 3 years ago

I would love to see support for this, either with first-class MDX support in TypeScript just like it does with JSX, or via plugin if it can be done. When using MDX in large content project (think large docs) with many contributors (especially non-developers), TypeScript can be of tremendous help to avoid issues.

In my case, we document many REST APIs (exposed as JSON, but the underlying language differs depending on the team) and TypeScript is helpful to make sure that people document the right JSON data types. Example:

type JSONLiteralType =
  | 'string'
  | 'number'
  | 'object'
  | 'array'
  | 'boolean'
  | 'null';

type ParameterProps = {
  name: string,
  type: JSONLiteralType,
  children: React.ReactChildren,
};

export function Parameter({ name, type, children }: ParameterProps) {
  return (
    <>
      <p><code>{name}</code></p>
      <p>type: {type}</p>
      {children}
    </>
  );
}
<Parameters>
  <Parameter name="myParam" type="string">

  Some description that uses **Markdown**.

  </Parameter>
  <Parameter name="myOtherParam" type="bool">

  Nope, you're not sending C++ over the wire!

  </Parameter>
</Parameters>

Another use case where TypeScript comes in handy with MDX is with template literal types. If you have internal link components, you can statically check them.

type FancyInternalLinkCmp = {
  url: `/doc/${string}`;
  label: string;
};
Kingwl commented 3 years ago

In my memory. @orta might has some work on this (or a plugin)?

orta commented 3 years ago

I explored mdx tooling a bit for the TypeScript website, but I think the heart of this issue is probably #14419 and https://github.com/microsoft/TypeScript/issues/38736

I'd say it's very unlikely that TypeScript the compiler (as shipped out of the box) is probably not going to support file formats like .mdx, .vue, .svelte, .html etc. Files which have JS in them, but it is an subset and requires work to 'connect' them to outer js/ts files. ( JSX is an exception, and while I wasn't around when JSX support was decided, I'd bet it was because it is a very very common extension of JavaScript and that's TS' domain. )

Today, if you want TypeScript support for mdx, you would do what we do with Svelte/Vue etc. Someone create an LSP which forwards the right calls to the TypeScript TSServer for the parts which are JavaScript. If that code is not vanilla JavaScript/TS, you transform it into a format which is usable in TS (vue/svelte) and handle the converting the error codes back up to the outer document.

https://github.com/microsoft/TypeScript/issues/38736 is a request to allow rolling most of that infra into a plugin which runs off the TypeScript TSServer and personally I like the idea and will keep bringing it up internally.

karlhorky commented 3 years ago

There's an issue in vscode-mdx for IntelliSense support, which I'm assuming has a lot of overlap with this issue: https://github.com/mdx-js/vscode-mdx/issues/165

bodograumann commented 2 years ago

This is definitely worthwhile prioritizing. MDX v2 just released with many great improvements and usage is climbing further: Screenshot_20220301-165853

kyleknighted commented 2 years ago

I stumbled across this Issue while searching for type checking Storybook. And, while I haven't tried it yet, I did see that @Yama-Tomo is working on this in https://github.com/Yama-Tomo/type-checking-MDX-in-storybook

Figured I would share it here incase anyone else is interested!

subskribe-kevin commented 2 years ago

Love the idea but without Typescript IMO MDX is dead on arrival.

Would LOVE this but it's just not going to happen. Especially after my team embraced Typescript

remcohaszing commented 1 year ago

I added TypeScript based IntelliSense in https://github.com/mdx-js/mdx-analyzer. It's based on TypeScript, but I don't think this is in the scope of TypeScript to include is in the core. I recommend to close this issue 🙂

ramosbugs commented 1 year ago

@remcohaszing this looks amazing! however, I don't think an IDE integration is a substitute for CLI-based compiler support, which is required if we want to typecheck MDX files within CI pipelines. there are also plenty of folks who use other IDEs (e.g., JetBrains-based ones) or no IDE at all. please don't close this issue...

remcohaszing commented 1 year ago

I wholeheartly agree with that. There’s an issue for creating a CLI (https://github.com/mdx-js/mdx-analyzer/issues/292). Also it’s all based on LSP. This hasn’t been released yet, but once it has, this can be leveraged by other editors, including JetBrains.

I’m also getting involved with the Volar.js team. Volar will integrate not only MDX IntelliSense, but also Vue, Astro, etc.

So it’s all coming. You can try MDX IntelliSense already in VSCode. However, as per https://github.com/microsoft/TypeScript/issues/36440#issuecomment-785139691, I don’t think this is ever going to be implemented as a core part of TypeScript.

cobbvanth commented 1 year ago

This is 100% necessary going forward. 2 way typesafety between the page and the .mdx file would make it the clear solution for blogs, docs and much more.

abder commented 1 year ago

Is there any update on this?

Thundercraft5 commented 1 year ago

It has been 3 years since this issue was opened, and MDX has reached 20M downloads a month as of writing. The lack of Typescript support in MDX files has prevented me from effectively utilizing MDX to its full potential as part of a large-scale project - something TypeScript touts as its strength. If TS support could be added, it would allow a total and comprehensive framework by combining it with other frameworks like NextJS.

lucastobrazil commented 7 months ago

Any update on this one? Would be SO good

remcohaszing commented 7 months ago

MDX Analyzer is now based on Volar. The MDX language server is no longer behind an experimental flag for VS Code. Both MDX Analyzer and Volar are stable to use, but also still under active development. Unfortunately a CLI is still not supported.

lucastobrazil commented 7 months ago

@remcohaszing awesome! Pardon my ignorance but does this basically mean if I have the main "MDX" VSCode extension then I should be able to interpret typescript inside MDX files? Or is there additional configuration to be added?

remcohaszing commented 7 months ago

No, MDX doesn’t support TypeScript syntax. It does support types in JSDoc like this:

{/**
  * @typedef Props
  * @property {string} name
  */}

{/**
  * @param {string} message
  * @returns {string}
  */}
export function print(message) {
  console.log(message)
  return message
}

# Welcome {props.name}

Note that MDX files are treated like JavaScript, so TypeScript support is subtle. To get the full red-squiggly-line experience, you need to enable the checkJs compiler option (for now).

lucastobrazil commented 7 months ago

@remcohaszing thanks for the clarification! Maybe jsut to be more specific, i guess its less about interpreting typescript, more about intellisense.

# My MDX File

// ```jsx
<MyTypedComponent foo="bar" />
// ```

In the above, can we get intellisense to tell me if foo accepts string?

remcohaszing commented 7 months ago

You won’t get IntelliSense for this particular example. What is MyTypedComponent? Where does it come from? Support for this is tracked in https://github.com/mdx-js/mdx-analyzer/issues/260. I’m open to ideas.

You will get IntelliSense if you add an import:

import { MyTypedComponent } from '../components/MyTypedComponent.js'

# My MDX File

<MyTypedComponent foo="bar" />
lucastobrazil commented 7 months ago

You won’t get IntelliSense for this particular example. What is MyTypedComponent? Where does it come from? Support for this is tracked in mdx-js/mdx-analyzer#260. I’m open to ideas.

Ah yes, sorry it'd have an import. (We're using Gatsby and passing all components via the MDXProvider so we don't need to explicitly import them into each MDX File. But I can see why we would probably need to in order to help VSCode recognise the component and its type.

For context, we're using MDX for a component library documentation site with code editable snippets. documentation(https://www.vitalitydesignsystem.com/components/avatar/ as an example)

In order to render the editable code (uses React-Live under the hood), we need to place all the code blocks in backticks, so ideally the intellisense can also read within those code blocks too.

Something like:

import { MyTypedComponent } from '../components/MyTypedComponent.js'

# My MDX File

<MyTypedComponent foo="bar" /> // intellisense works

.```jsx
<MyTypedComponent foo="bar" /> // intellisense doesn't work but should
.```
remcohaszing commented 7 months ago

If you paste this code in the MDX playground, you’ll see that the part you’re not getting IntelliSense for, is compiled to a string.

It may have worked as you expected before in MDX 1, I’m not sure. If you’re still using MDX 1, I strongly suggest you upgrade to MDX 3.

If you have further questions / issues, please use the MDX analyzer issue tracker or MDX discussions. This is getting off-topic for this issue. :)