This document lays out the goal, strategy, and guidelines for adding
TypeScript types for components within
@carbon/react
.
The goal of this workstream is to provide as much downstream value to consumers who are using TypeScript, as quickly as possible, while writing the least amount of TypeScript.
The goal is not to convert the entire codebase to TypeScript right now.
By adding TypeScript types to components we anticipate a number of benefits:
- Developer productivity will increase due to Component API's being self-documenting and providing tight integration with code editor intellisense.
- The quality of products developed will increase due to more stable, correct,
and thorough component API typings provided first-party through
@carbon/react
itself. - Maintenance of the types themselves will be simplified by not having to go through the DefinitelyTyped contribution process/system.
Despite these benefits, adding TypeScript to the codebase is still a large shift for the developer community surrounding the Carbon Design System. Most projects are not using TypeScript, and contributors are more likely to not have in-depth knowledge of TypeScript.
The bar to contribute to Carbon should be as low as possible to facilitate experimentation, innovation, and progress within the system. Adding TypeScript raises this bar of contribution adding additional friction to even the smallest of pull requests.
We believe the majority of the benefits of TypeScript can be provided to consumers without needing to convert the entire codebase to use TypeScript. Overall, this effort will be focused on limiting the amount of TypeScript within the repository for now.
TypeScript will be incrementally adopted, focusing first on adding types to
components prop APIs that are included as part of the public API of
@carbon/react
.
Internal components, helpers, function, etc. will not initially be typed. These
internal files/components not included in the public API should be left as
.js
, given a
jsdoc type annotation
of /** @type any */
, and
errors should be enabled
by adding // @ts-check
to the first line in the file.
Other packages, such as @carbon/icons-react
, @carbon/elements
, etc will not
initially be typed.
Within this incremental adoption strategy, for now types will not be bound to semver.
This means that types are provided on an as-is basis. Ideally types will be stable and not ship breaking changes, but the reality is typings may at times be incorrect, outdated, or missing. Full details available within our versioning documentation.
Below is a general outline of what needs to be done for each component within the repository. There is an issue tracking curring status of this effort, #12513
-
Change extension to
.tsx
via git (do not simply rename)- e.g.
git mv packages/react/src/components/ComponentName/ComponentName.js packages/react/src/components/ComponentName/ComponentName.tsx
- e.g.
-
Copy the proptypes def to above the component definition
-
Retool the proptypes to be a ts interface
-
Look for any legacy types for the component, previously provided via DefinitelyTyped
- Copy these legacy types over to your working file and use them as a starting point.
- NOTE: If there are legacy types available, these were originally provided
for
carbon-components-react@v7.x
and may be out of date. - Even still, it would be best to have as much parity as possible between
legacy types for
carbon-components-react@v7.x
and the new typings we're providing for@carbon/react@1.x
. - After copying them over to your working file, ensure the legacy types don't require any updates to match the current component proptypes specification.
-
Fix errors as they appear
-
Do not add types to internal components or functions that are not exported as part of the Public API.
- Leave internals as
.js
- Add a
jsdoc type annotation
of
/** @type any */
- Enable errors
by adding
// @ts-check
to the first line in the file.
- Leave internals as
-
Test your changes - there are a few options here:
- At the bottom of a file, write a dummy component that uses the component that you’re converting to ensure that you can still pass all appropriate props that you need to.
- Take a storybook example for a component, copy and paste it into the bottom of the .tsx file and validate whether or not it accepts the props as you’ve defined them
-
Submit a pull request for the changes
- Please keep pull requests as small as possible
- Avoid adding additional components to a single PR unless necessary
- Link to close the related issue,
e.g.
Closes #12513
-
Ask questions if you get stuck!
- The team is available on slack
#carbon-wg-typescript
, discord, or on the issue itself.
- The team is available on slack
- If it's not on the storybook, it's probably not public.
- The entire Public API is snapshotted, you can search the snapshot here. If it's not included there, it's not part of the public API.
- Yes
- Yes
- Duplicate comments between the proptypes definition and ts interface
- Storybook prefers react-docgen for now
- Once we have ts interfaces for everything we can switch out the storybook config to favor TypeScript docs
- Above the component definition (likely the top of the file)
- The component implementation should be sandwiched in-between the ts interface and the proptypes definition