We're going to add first-class support for TypeScript and be an even better experience for JavaScript as a result.
Make the project that's created by yarn create redwood-app support TypeScript:
*.js files in create-redwood-app repo to TypeScript.create-redwood-app package.tsconfig.json file in a projectMake the generators TS/ JS aware:
👉See sub-Tracking Issue #523
The api side:
.ts files via the importAll.macro (tests!)context, is that a problem in the ts world?.ts files.The bridge between api and web:
currentUser returned from api/src/lib/user.ts with getCurrentUser in useAuthThe web side:
.ts/ .tsx files?Framework/Packages
Tooling
Is there a Branch?
Are you planning to move the core itself to TS? The router needs to have types to work well in TS projects.
Currently in process by Peter:
Are you planning to move the core itself to TS?
Yes indeed. I believe @jeremyscatigna might have a start on this already. True, Jeremy?
In this adding of "first class typescript support", is there a line item for generating types for gql queries? Something like apollo-codgen? This is currently one of the pain points when integrating with any API (whether REST or graphql) and if that would be included in the Redwood framework that would be amazing and make for an awesome and very type-safe coding experience.
+1 on generating types for gql queries. The graphql-code-generator project might also worth considering as it generates typesafe React Hooks, HOCs, etc for pre-defined query fragments.
Is there a rough timeline for TypeScript support? E.g months, 1/2 year, 1 year?
Hi @marceloverdijk it’s a top 3 priority (on the list with Auth and Jest tests, for example), but the progress has admittedly been slow. I know we _want_ it to be “months”. But that’s all the certainty I can commit to regarding a rough timeline.
What I _could_ commit to, personally, is helping organize a collaborative effort around this. I know:
…but we haven’t really rounded up critical mass. So taking this as a nudge in that direction, and as a next-step I just this created a Forum topic (below). Chime in you’re available + interested:
https://community.redwoodjs.com/t/team-typescript-for-those-who-want-to-help-add-ts-support/369
Thx @thedavidprice for the honest answer. Much appreciated!
I'm mainly a Java developer, taking some side paths in the evening, like JS/TS. But I'm not a level to contribute unfortunately. But I will follow the thread with a lot of interest.
Our development configurations are now "TypeScript aware" via #438, this means that if you rename the .js files to .ts and add .tsx files that the development servers will understand how to work with those - and you should not be personally blocked by developing in TypeScript in a Redwood project.
The next steps are to figure out if building a project is working, and to add types to the redwood router.
We'll add support for starting a redwood project in typescript, and making sure the generators generate TypeScript.
EDIT: added an example that showcases some of the techniques discussed here
Those are the tools at our disposal. But what are the challenges?
tsconfig.json, which are actually equivalent to the settings in jsconfig.json. (in fact, jsonfig.json is a subset of tsconfig.json)Redwood uses the DirectoryName convention extensively.
This convention is meant to improve Developer Experience by allowing more significant file names (instead of having multiple files named "index.js")
This is enabled via a webpack plugin and, functionally, it extends webpack's module resolution logic by adding an extra alternative:
For the following import:
import MyComponent from "src/MyComponent"
Normal Lookup (simplification)
src/MyComponent.(t|j)sx?
src/MyComponent/index.(t|j)sx?
node_modules...
With DirectoryName convention:
src/MyComponent.(t|j)sx?
src/MyComponent/index.(t|j)sx?
src/MyComponent/MyComponent.(t|j)sx? <---- extra step
node_modules...
provideDefinition(...))If we're already generating code, we could "declare global var"iables for each of these pages.
This would make the identifiers available so the compiler would not complain, but it would not
allow "jump to definition" to work correctly, since it would only take us to the generated declaration.
The runtime bundling magic would still be left to webpack.
Solution?
If everything else fails, we can change the way TypeScript works :). This might sound crazy, but I'll bring it up to be exhaustive.
How can this be distributed?
I've seen two approaches:
TypeScript SDK folder to use via config, or we could automatically output/create a .vscode/settings.json file)Challenges:
Challenges:
Maybe I could take a hit at writing type definitions for <Route>, <Link>, and <Private> at the moment
@koolamusic that would be fantastic! Looping in @peterp here.
Maybe open a separate Issue (linking back to this one) to get started? And definitely don't hesitate to let us know what questions + clarification + help you need along the way.
🚀
@thedavidprice do you have any developer guidelines for adding types? Do you want to store them in one big file, or separate definitions into linked files? Do you want to keep definitions in Redwood repo, or shall it be tracked in the @types repo?
Hi @tomitrescak! Thanks for checking in here. @peterp is the one to provide an update as this issue is (in a good way) out of date. And your question is a bit of "it depends" 😆. For the Framework (this repo redwoodjs/redwood) we have a mix of approaches. For the application development template (redwoodjs/create-redwood-app) there's a lot more customization involved and (I believe) includes storing in a big file.
@tomitrescak I think it's okay to start out with one file for some packages, while others could use a type-per-module approach to separate the definitions. With regards to the developer guidelines, have you seen https://github.com/sindresorhus/typescript-definition-style-guide ? would love to know what your thoughts are
I've added the type defs for the router over here: https://github.com/redwoodjs/redwood/pull/1110
Once this is finished, maybe you can coin the term TAMStack (TypeScript, API, Markdown) :D
Most helpful comment
then we need to guarantee that a Redwood project works with the TypeScript compiler out of the box. In other words, Redwood code MUST be valid TypeScript code.
EDIT: added an example that showcases some of the techniques discussed here
Those are the tools at our disposal. But what are the challenges?
Challenges
Using path aliases (src/*) instead of relative imports
tsconfig.json, which are actually equivalent to the settings injsconfig.json. (in fact, jsonfig.json is a subset of tsconfig.json)Directory Name convention
Redwood uses the DirectoryName convention extensively.
This convention is meant to improve Developer Experience by allowing more significant file names (instead of having multiple files named "index.js")
This is enabled via a webpack plugin and, functionally, it extends webpack's module resolution logic by adding an extra alternative:
For the following import:
Normal Lookup (simplification)
With DirectoryName convention:
Can it be mapped to TypeScript?
Auto Imports on Routes.js
Possible Solution: Language Service Plugin
provideDefinition(...))Possible Solution: Code Generation
If we're already generating code, we could "declare global var"iables for each of these pages.
This would make the identifiers available so the compiler would not complain, but it would not
allow "jump to definition" to work correctly, since it would only take us to the generated declaration.
The runtime bundling magic would still be left to webpack.
Possible Solution: Routes.js must always be JS (not TS)
Named Routes
importAll.macro
Cells
you end up using when you import it.
Solution?
(*) Providing a Custom TypeScript Compiler
If everything else fails, we can change the way TypeScript works :). This might sound crazy, but I'll bring it up to be exhaustive.
How can this be distributed?
I've seen two approaches:
Publish a separate NPM module
TypeScript SDK folderto use via config, or we could automatically output/create a.vscode/settings.jsonfile)Challenges:
Monkey Patch
Challenges: