[RFC] TypeScript migration
See original GitHub issueSummary
TypeScript is a superset of Javascript – all Javascript is valid Typescript. However, once a project has typescript enabled, you can annotate your code to provide type hints to your users and other developers.
Just as shared styles between Carbon frameworks improves user experience, so to would shared behavior. Typesafety allows us to ship components that perform and behave as expected.
Related issues: #1296, #727, #1103, #580
Motivation
End users, product developers, as well as Carbon developers would all benefit from the addition of type safety to Carbon products
- End Users – by shipping more resilient, bug free components end users will encounter fewer unexpected edge cases
- Product developers – developers would be guided towards proper API usage and would be alerted to new or changed apis.
- Carbon developers and Typescript developers –
- Fewer
Uncaught TypeError(Cannot read x of undefined
or spelling errors means more time on real issues. - Fewer undefined refs and instance properties
- Reduce reliance on
null
andundefined
guards means more resiliant APIs – Alerted to misuse of props, state, third-party library, and dom errors while writing your code.
Design
There are currently to main ways to compile typescript into javascript(the typescript compiler, and through babel. Since our project is already using Babel, switching to typescript would be unnecessary.
Namespaces and const enums are not supported by the babel compilation, however, this can be mitigated with compiler configuration.
As we look toward migrating codebases to a mono-repo, typesafety will offer a means to share types between projects and permit large scale refactors with confidence.
Drawbacks
- Time spent onboarding carbon devs to typescript
- I volunteer as tribute
- Friction to carbon contributors new to the project
- would empower them to make more meaningful changes
- would reduce friction for folks onboarding to product teams
Alternatives
Non-Typescript
- FlowType
- call-site type checking is nice
- Lots of projects switching to TS(Jest, Expo, Atlassian, Yarn.
- Far fewer third party integrations 1/10th of the questions on SO
- JSDoc
- some bugs around object types
- errors in jsdoc means no warnings/errors it just won’t get annotated
TypeScript without migration
These solutions offer some of the benefits of TypeScript types with different drawbacks. While the core library would still be standard JavaScript maintaining types would be a manual effort.
The main issue with these strategies is that they require a much more manual effort up front and the types would be of lower quality than those generated natively from the project in situ.
Definitely-typed
- Types published using the DefinitelyTyped repo https://github.com/DefinitelyTyped/DefinitelyTyped
- Recommended solution from TS team for no TypeScript projects
- Rely on community involvement
- Issues keeping types in parity with new library features and changes
- We don’t benefit from the types internally
Internal .d.ts
files
- Less opportunity for community engagement, relies more on project maintainers to maintain types
- Types are version tied to the actual code, making updating types an imperitive with each PR.
- Example: https://github.com/mui-org/material-ui/tree/next/packages/material-ui
Adoption strategy
At no point will typescript migration stop or prevent work on the project. TypeScript can get out of the way when necessary (@ts-ignore
and any
or unknown
types). It will never break builds unless we chose to enable that behavior.
While each of the Carbon javascript projects would benefit from the addition of types. I believe the most valuable library at this time would be carbon components react (CCR).
Since we already have some run-time type checking through prop-types
, we already have a starting point. In addition, thanks to prop-types
CCR developers are already at least slightly familiar with the constraints imposed by types.
Conversion path
A – Just rename everything to .ts
and .tsx
-
The first pass at converting the project will rename the files and add babel, storybook, and jest configuration to handle these new file types.
-
The initial config will have the loosest possible config. Separate PR’s will be made to turn on each of the strict-mode rules separately resolving issues as they come up.
-
Any objective errors uncovered as a result of the conversion will be resolved as part of the same PR.
-
Prop types will be defined at the same level of specificity as the
prop-types
. No unnecessary types added. -
Types can be shipped from day one
B – Leave the files as .js
config enable allowJS
and checkJS
- Recommended by TypeScript team for large projects using the TypeScript compiler (likely not us)
- All new code should be written as
.ts
- Gradually migrate files to
.ts
- Types can be shipped once all
.js
files are converted to TypeScript
Migration stories from others
- hootsuite: Thoughts on migrating to TypeScript
- clayallsop: Incrementally-migrating-javascript-to-typescript-565020e49c88 'Incrementally Migrating JavaScript to TypeScript
- pleo: Migrating a Babel project to TypeScript
- mstsreactconversionguide: TypeScript React Conversion Guide
- entria: Incremental Migration to TypeScript on a Flowtype codebase
Issue Analytics
- State:
- Created 4 years ago
- Reactions:11
- Comments:20 (11 by maintainers)
Top GitHub Comments
Do you have any updates on this? I think moving into TS will really improve the developer experience, including your own.
Moved my typings to a definitelytyped PR: https://github.com/DefinitelyTyped/DefinitelyTyped/pull/37442