React-md: Add TypeScript Support

Created on 15 Dec 2016  ·  39Comments  ·  Source: mlaursen/react-md

enhancement

Most helpful comment

If anyone is looking at the progress of this issue... the typescript support is in a beta state and available under the react-md@next tag. It also includes some of the changes for v1.1.0

Until v1.1.0 has been released, there is a temporary and incomplete documentation site available at
http://react-md.next.mlaursen.com that should hopefully be of some use.

All 39 comments

@mlaursen Instead of adding and maintaining a definition file, if you're open to having this project refactored to TypeScript, I'm willing to do it. Let me know what you think and I'll fork and refactor one of the components as an example.

Since I am still not fully up-to-date with typescript, wouldn't it still require the definition files? The flow I was guessing is that the react-md build process would still compile the components from typescript. This would allow for faster development times since you wouldn't need to compile these components as well in your apps?

That's correct, react-md build process compiles from typescript to javascript. There's a compilation flag called "declaration" for automatically generating a .d.ts file. So there's still a declaration file, you just don't have to create and maintain it manually.

Also, typescript support jsdoc, and that gets put in the declaration file as well. Would be great to see all the thorough documentation you've made for react-md props in my VS Code intellisense without anyone having to do any work to duplicate it and keep it up to date.

Ok, well I'm sold :)

I think the Autocomplete would be a good starting example since it is one of the more complicated and has class and ref functions.

A couple more questions:

  • How do React PropTypes work when mixed with the typescript interfaces? Does it automatically transform/compile/transpile the prop declaration into the corresponding PropTypes?
  • Would I need to switch my documentation server to using jsdoc instead of react-docgen for prop documentation?

Hm good questions.

1) Interfaces don't get transformed to PropTypes. You don't get runtime PropTypes checking with typescript. This is fine for typescript consumers of react-md because you get compile-time checking, but not for js consumers. I'll see if I can find a solution, otherwise we'd have to have both an interface and PropTypes for each component.

2) Probably. Maybe there's a bridge out there, I'll look into it.

I'll fork and start with Autocomplete to see how much of an undertaking this will be.

Whats the status of this? I see a branch from december. I'd really love to switch from material-ui to react-md and this is a huge part of that decision.

So the branch I made in December is _basically_ done. I just need to change the basic Event types to the ReactXEvent<target> thing and do some more testing in a repo someone made for me since I don't use typescript. It would be nice for someone to code review the types for me since I am guessing on everything :man_shrugging:

I had originally planned on releasing this with the 1.1.0 release to follow SemVer. I could cheat and do 1.0.2 though.

I haven't heard anything else about the Typescript rewrite, so I'm guessing it is too much effort.

I'm happy to review a PR if you'd like. I haven't used react-md yet but
been writing typescript for a while
On Tue, Jan 24, 2017 at 13:04 Mikkel Laursen notifications@github.com
wrote:

So the branch I made in December is basically done. I just need to
change the basic Event types to the ReactXEvent thing and do some
more testing in a repo someone made for me since I don't use typescript. It
would be nice for someone to code review the types for me since I am
guessing on everything 🤷‍♂️

I had originally planned on releasing this with the 1.1.0 release to
follow SemVer. I could cheat and do 1.0.2 though.

I haven't heard anything else about the Typescript rewrite, so I'm
guessing it is too much effort.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/mlaursen/react-md/issues/175#issuecomment-274938186,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAneTP2cdLkGzdoLrGgX-oFV2p6hkYkcks5rVmd6gaJpZM4LOh3E
.

That would be fantastic, thanks! I can do the event changes by Thursday and hopefully open up the pull request then. I'll try to decide if I want to cheat or not for the versioning. If I don't cheat, it might be awhile before this gets supported since the #197 will take a while to finish and is targeted for 1.1.0 as well.

@mlaursen I just found this tool: https://www.npmjs.com/package/react-to-typescript-definitions and it seemed to work when I dumped every component in react-md.. I'll check the output. If you're
react-md.d.ts.zip

@maxcan I checked the output and it is fairly accurate. The main concerns I have are that the callback function props aren't typed correctly --it just defaults to (...args: any[]) => any and it doesn't document any of the static or ref accessible functions.

I would love to be lazy and have this tool do it for me instead of manually updating it, but I feel like you're losing the benefits of Typescript when they aren't as accurate as possible. I'm not sure if that is true, I personally prefer the typelessness of javascript. Let me know what you think.

Well, the other beauty of typescript is incremental typing so if this is something that gives 80% of the value for 5% of the effort, it could be worth it. Can also use this as a starting point and edit as necessary.

Ok, I'll see how much I can programatically fix the output of using the react-to-typescript-definitions since a lot of fixes follow a typical pattern and compare the results to my other branch. I do like that the docgen comments are copied with the tool, so it can hopefully be picked up by your editors as well.

But as a side note... Would you happen to know how to correctly type a FileReader? The last thing I need to do in my branch is type the props here. (I guess I could default to any, Error, and Event?)

@mlaursen sorry for the slow reply. I think thats basically correct, looking at the diff around these lines: https://github.com/mlaursen/react-md/compare/feature/TypeScript-Support#diff-f6a7a428afd2f7f3a28207a5f00f6334R28 . Do you think that branch is good to merge? It will be easier to spot issues once I'm using it.

If its not ready but you do want to get it merged eventually, i can start using that branch. I just hate to do that if its not going to get merged.

Sorry, I haven't been actively doing this since I get distracted too much. I have a local commit for that existing branch that I can push up that does a few more fixes and _might_ be okay to merge. It has fallen behind though since I added more components and did bugfixes since then.

I also have another branch were I was working on using that react to typescript generator that I can push up. I really don't know which is better. (Probably first branch... I'm doing some _amazing_ regex replaces in the other branch to get more accurate typing).

I can push both of these up right now if that helps.

@mlaursen got the original feature/Typescript-support branch working yesterday and it looks pretty good. The only issue is that for things like TableRow the children property should be optional due to a typescript limitation. I just saw that you put up two new branches today. I'll experiment with them.

FYI, I can't get the feature/Typescript-Support-Automation branch to build. The npm run ts-defs command just outputs js. When I add the -e flag to run babel-node -e --presets=es2015,react --plugins=syntax-async-functions,transform-regenerator ./src/scripts/makeTSDefs.js I get this:

> babel-node -e --presets=es2015,react --plugins=syntax-async-functions,transform-regenerator ./src/scripts/makeTSDefs.js

/Users/max/development/github/react-md/node_modules/babel-cli/lib/_babel-node.js:94
  code = code.trim();
             ^

TypeError: Cannot read property 'trim' of undefined
    at _eval (/Users/max/development/github/react-md/node_modules/babel-cli/lib/_babel-node.js:94:14)
    at Object.<anonymous> (/Users/max/development/github/react-md/node_modules/babel-cli/lib/_babel-node.js:123:16)
    at Module._compile (module.js:571:32)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)
    at Module.runMain (module.js:605:10)
    at run (bootstrap_node.js:422:7)
    at startup (bootstrap_node.js:143:9)

Hmm... That is weird. What version of node are you using? It shouldn't really matter though.

But just a side note about that branch.. I haven't finished it yet, so it isn't actually writing the definitions out to files. Defining each component as a module through me off a bit and I was going for the bit more accurate definitions in this one.

I'm back to using a fork of the original branch: https://github.com/maxcan/react-md/tree/feature/TypeScript-Support I made some fixes here and there but also added the build products to the repo as it just made life much much easier.

also, node 7.6.0

Ok, cool. I think for 1.1.0, I'll stick with the feature/Typescript-Support branch -- the automation will come later. My goal is to release my react-md@next tag by Wednesday for a 1.1.0 preview with typescript support. I'll merge in the couple of fixes I see on your branch.

Until it is out, I'll also try to publish the documentation site at https://react-md.mlaursen.com/next or something.

Great! If that's the branch you're using I'll start writing PRs and issues
against it.
On Mon, Feb 27, 2017 at 08:57 Mikkel Laursen notifications@github.com
wrote:

Ok, cool. I think for 1.1.0, I'll stick with the
feature/Typescript-Support branch -- the automation will come later. My
goal is to release my react-md@next tag by Wednesday for a 1.1.0 preview
with typescript support. I'll merge in the couple of fixes I see on your
branch.

Until it is out, I'll also try to publish the documentation site at
https://react-md.mlaursen.com/next or something.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/mlaursen/react-md/issues/175#issuecomment-282780329,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAneTN3edUKa3Z-ULk0KE-V1-n4jBqKNks5rgwCJgaJpZM4LOh3E
.

Ahh, just a side note... Once I merge it in, most of the work is going to be back in the release/1.1.0 branch instead of the feature/Typescript-Support. I ended up adding more features/components since I started the typescript branch, and it'll be easier to maintain in that branch

Awesome. I'll wait for the merge then work against the 110 branch. Having
said that, it's a busy week so I might not get to do much at all
On Tue, Feb 28, 2017 at 09:57 Mikkel Laursen notifications@github.com
wrote:

Ahh, just a side note... Once I merge it in, most of the work is going to
be back in the release/1.1.0 branch instead of the
feature/Typescript-Support. I ended up adding more features/components
since I started the typescript branch, and it'll be easier to maintain in
that branch


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/mlaursen/react-md/issues/175#issuecomment-283115185,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAneTNE2pD-FSfPht36Qvf-als2qWr6zks5rhF_rgaJpZM4LOh3E
.

If anyone is looking at the progress of this issue... the typescript support is in a beta state and available under the react-md@next tag. It also includes some of the changes for v1.1.0

Until v1.1.0 has been released, there is a temporary and incomplete documentation site available at
http://react-md.next.mlaursen.com that should hopefully be of some use.

@mlaursen I tried it yesterday and it didn't quite work. I am sorry I can't give more feedback as of now.
Tslint couldn't find anything under import Button from 'react-md/lib/Buttons/Button'

Tried it and everything seems to work very nicely, at least using import { Button } from "react-md".

Not sure if you can require use of some props but could be useful if buttons required either flat={true} or raised={true} or whatever else there is, since without it they look weird.

Ahh ok. It looks like I goofed. I need to copy the definitions into the lib folder as well.

I wasn't sure how to do that with typescript definitions. It should be giving you a prop type validation error though.

You were right, it does print an error in the console 👍, I was just wondering if it could be a Typescript compiler error.

Other than that this lib is great and by far the best out of React material libs 🥇, it just looks like there are a few recent changes that haven't made it into typings yet, like ListItem prop visible.

Thanks, I'm glad you think so!

I just released [email protected] which should address most of the type issues. If any other types are invalid, feel free to join in on the typescript channel in Slack

Cool, tested it out.

This is an error that happens when typescript noImplicitAny is set to true:

Failed to compile.
Error in node_modules\react-md\lib\NavigationDrawers\NavigationDrawer.d.ts
(81,42): error TS7008: Member 'MobileDrawerTypesType' implicitly has an 'any' type.

Another thing I noted is ListItem's visible or isOpen being of type boolean. It's difficult to not pass a prop conditionally with react so maybe boolean | null could be better.

The slack invite page thingie is also broken (Application error).

Oh yeah. It looks like I ran out of free heroku hours for this month. So you can wait for tomorrow, or I can send you an invite manually if you'd like (you can send an email to my gmail and use that for your account).

I'll try to see what's up with the MobileDrawerTypesType. I'm still unsure of everything that should be exported from these modules. My _very_ simple typescript definitions tests passed, so might be better to figure out additional ways to test.

I am running into this too.

Error in node_modules/react-md/lib/NavigationDrawers/NavigationDrawer.d.ts
(81,42): error TS7008: Member 'MobileDrawerTypesType' implicitly has an 'any' type.

Changing line 81 of NavigationDrawer.d.ts:
mobileDrawerType: MobileDrawerTypes, MobileDrawerTypesType, to:
mobileDrawerType: MobileDrawerTypes | MobileDrawerTypesType,
fixes the issue for me. else I have to set skipLibCheck to true in tsconfig.

I'd be happy to raise a PR, if what i'm saying is correct. I am fairly new to typescript.

I also seem to be be having difficulty in using some props which reference a key.
eg: I am currently messing about with the DropdownMenu:

whenever I add a position prop of any Positions value: position={DropdownMenu.Positions.BELOW} like in the docs, I get the tsc error:

Type '"below"' is not assignable to type 'LayoverPositions | undefined'.

However position={DropdownMenu.Positions} satisifes tsc, but that does not accomplish anything useful.

I can change the LayoutPostions type of Layover.d.ts to:
export type LayoverPositions = 'tl' | 'tr' | 'bl' | 'br' | 'below';
and it works, however I lose the key-value alias prop style (TOP_LEFT is 'tl',TOP_RIGHT is 'tr'... )

How do I use these restricted props in typescript?

I'm also running into the issue with LayoutPositions above.

To fix a separate issue where MenuButton didn't support icons I had to change MenuButton.d.ts to allow Button properties on the MenuButton component.

export interface MenuButtonProps extends DropdownMenuProps {

changed to

export interface MenuButtonProps extends DropdownMenuProps, ButtonProps {

It looks like initial support is mostly here. I'll just need to learn typescript a bit more to figure out how to correctly export component enums for usage. I'd definitely welcome any PRs to fix or show how to do that.

Thanks so much for adding this. I've migrated mostly of our project to this version and created issues/PRs for everything we found!

Thanks again for your work on this!

Thanks a bunch! I'll be doing a patch today with the the fixes you and some people in Slack have suggested.

It's awesome - way better. Definitely thanks all round!

Was this page helpful?
0 / 5 - 0 ratings