Closed andrewserong closed 9 months ago
Hello everyone :wave: I want to work on this issue. Can anyone tell me if I need to convert all js file to typescript. (example in DropdownMenu have index.js
, index.native.js
, test folder
and stories
folder) Do I need to change only index.js
to typescript or all files.
Hello everyone 👋 I want to work on this issue. Can anyone tell me if I need to convert all js file to typescript. (example in DropdownMenu have
index.js
,index.native.js
,test folder
andstories
folder) Do I need to change onlyindex.js
to typescript or all files.
Hey @rajnish93 , thank you for your interest! I would ask you to wait before contributing to this issue, as I'm going to update the list of components that need refactoring. Some of the refactors are quite complex and it's probably better if we champion a few of them first to understand any caveat along the way.
We'd still love to get your help further down the line though, if that's ok!
Alright, I've edited this issue's description and added all components/folders in the package.
There's still a couple of things of which I’m not sure yet:
WordPressComponent
type. On the other hand, we may want to keep the refactor as lean as possible and only aim changing file extension, fixing TS errors, and (maybe) adding a types.ts
file. We should also consider that certain components are still written in class form — in that case, should we first refactor them to functional components in a separate PR preceding the TypeScript refactor?Would love to hear folks' opinions on this (cc @mirka @diegohaz @sarayourfriend )
so far, even with fully-typed components, we left a few files still in JS — in particular unit tests, storybook examples, and react native files. Is there a particular reason for each of those?
From a "value" perspective I don't think there's a compelling reason to spend contributor time on updating unit tests and storybook examples to use TypeScript.
React native is a separate beast altogether. I'm not sure what it would take to convert those to TypeScript or if it's even possible with the current tooling.
Where to draw the line in the refactor? On one hand, as we refactor, it would good to hook components to the context system, and therefore use the WordPressComponent type. On the other hand, we may want to keep the refactor as lean as possible and only aim changing file extension, fixing TS errors, and (maybe) adding a types.ts file. We should also consider that certain components are still written in class form — in that case, should we first refactor them to functional components in a separate PR preceding the TypeScript refactor?
From a perspective of what will benefit the consumers of the components package the most, just adding types is a big win. The rest of the things help bring the components package inline with itself (context, Emotion, hooks, etc) but don't necessarily have a big effect on the consumers of the package. While converting to TypeScript will increase the maintainability of the package, it probably has the greatest effect on consumers of it. Given it will be the largest most widely used package to be typed in Gutenberg, it will also serve to evangelize the benefits of TypeScript to other contributors, many of whom may still have doubts that TypeScript is a valuable tool to learn in addition to everything else they've already been asked to learn to be able to contribute to Gutenberg (JavaScript, React (twice over now given the transition to hooks happened during Gutenberg's lifetime), etc).
Remember, we don't refactor just because we can. In the spirit of this, we should continue only converting to TypeScript (instead of just annotating with JSDoc) when necessary. This was the agreement made in the Make post that added TypeScript to Gutenberg (see When to use TypeScript for existing code
section).
From a "value" perspective I don't think there's a compelling reason to spend contributor time on updating unit tests and storybook examples to use TypeScript.
I see your point, although I liked the idea that a component would have all of its files in TypeScript, rather than a mix of TypeScript and JavaScript. But definitely not a priority when considering which order we should tackle components.
React native is a separate beast altogether. I'm not sure what it would take to convert those to TypeScript or if it's even possible with the current tooling.
I'll be seeking more advice from mobile folks on this matter specifically and come back with updates
Remember, we don't refactor just because we can. In the spirit of this, we should continue only converting to TypeScript (instead of just annotating with JSDoc) when necessary.
Thank you for the link! I would argue that a refactor to TypeScript has become, for this package, quite a necessity. As you explained too, it will bring benefits to the consumers of the package by adding first-party types, allowing us to deprecate (and stop maintaining) the DefinitelyTyped
ones
Another added benefit that you mentioned is maintainability: the package is currently very fragmented in terms of technology:
Aligning the components in the package on the same tech stack as much as possible would make it easier for devs to maintain the package and for new folks to contribute to it.
Having said that, in the context of this TypeScript refactor, I think it makes the most sense to keep the refactor as "lean" as possible — i.e. adding the necessary types and refactoring the code without (theoretically) introducing any runtime changes. We can only iterate later on in case we want to introduce more changes to each component when necessary.
Having said that, in the context of this TypeScript refactor, I think it makes the most sense to keep the refactor as "lean" as possible — i.e. adding the necessary types and refactoring the code without (theoretically) introducing any runtime changes. We can only iterate later on in case we want to introduce more changes to each component when necessary.
Yes! I think this is the clearest path forward for this issue, otherwise the scope is far too large!
so far, even with fully-typed components, we left a few files still in JS — in particular unit tests, storybook examples, and react native files. Is there a particular reason for each of those?
React native is a separate beast altogether. I'm not sure what it would take to convert those to TypeScript or if it's even possible with the current tooling.
Hi. 👋🏻 I spoke briefly with @ciampo about native modules in a chat, but I wanted to share thoughts here as well. Thanks for the ping on this topic! 🙇🏻
TL;DR: Native modules can import shared/web TypeScript modules successfully, both the ones that exist today and any modules converted in the future. Native modules themselves cannot be easily converted to TypeScript themselves currently due to https://github.com/microsoft/TypeScript/issues/21926.
I do believe the native mobile Gutenberg contributors are interested in typed JavaScript for the project. The project would likely gain a lot of benefit from static analysis and code completion. Also, leveraging TypeScript with React Native is fairly common in the community at large.
That said, I researched the possibility of using TypeScript for native modules in this repository mid last year. Unfortunately, it does not appear possible due to https://github.com/microsoft/TypeScript/issues/21926, which outlines TypeScript tooling's lack of support for platform-specific files.
MissingEdit
imports Icon
from @wordpress/components
. index.native.[tsx|js]
. The definitions from the sibling web module is always loaded, as there is no way to configure TypeScript to load platform-specific files. While a native module can technically be migrated to a TypeScript file, there is likely little value in a native module TypeScript file if (1) there is no way to enforce adherence to the native TypeScript module interface and (2) its interface cannot diverge from the sibling web TypeScript module.
So, with all of that, my personal opinion is that it is likely not worth refactoring native modules to TypeScript until some of these shortcomings in TypeScript's tooling are addressed, namely, https://github.com/microsoft/TypeScript/issues/21926 and https://github.com/microsoft/TypeScript/issues/420.
🔴 Native modules cannot be statically typed checked via CI or editors as there is no way to configure TypeScript to load https://github.com/microsoft/TypeScript/issues/21926 or https://github.com/microsoft/TypeScript/issues/8328#issuecomment-219254627.
It looks like once https://github.com/microsoft/TypeScript/pull/48189 gets released we'll be able to configure TypeScript to load the .native
files. 😄
Update:
a first version of the TypeScript refactoring guidelines has been added to the @wordpress/components
package guidelines.
From now on, we will be starting to accept help on this task — please follow the guidelines, open a draft PR and either post about it in this issue, or ping me and/or @mirka directly in the PR.
Thank you!
I have marked Tooltip
component as a blocker because refactoring is being considered in #42753.
Hope it's OK I added a link to my friend Mike's ToolbarButton PR to this issue's top comment.
Just wanted to make sure there's no duplication of work.
Looks like FooterMessageControl
is native only at this point?
Looks like
FooterMessageControl
is native only at this point?
Good point, I'm going to remove it from the list.
I think we can close this tracking issue now that we are practically done! At the component level, we only have the migration to CustomSelectControl
v2 left, which is progressing and tracked separately (#55023).
Great work everyone 🎉
Related to #30503, #28399 and #27484
Context ✨
We would like to refactor the entire
@wordpress/components
package to TypeScript.Some components are already written in TypeScript, while the majority of the code is still written in JavaScript.
By refactoring the whole package to TypeScript, we would be able to take advantage of type safety, while also providing first-party types to the package's consumers (instead of the third-party ones).
A fully-typed set of components would also potentially allow us to generate documentation programmatically based off types.
Details of the refactor 🔍
The refactors should introduce the least amount of runtime changes possible — ideally none. All JS files should be refactored to TypeScript.
You can also refer to the TypeScript migration guide in the
@wordpress/components
package guidelines., and reference an existing component likeItemGroup
orToolsPanel
.Next up
Once the refactor to TypeScript is complete, we'll be able to:
List ⚒️
The components in the
exclude
list of our tsconfig are particularly high priority.AlignmentMatrixControl
(packages/components/src/alignment-matrix-control
) #46162AnglePickerControl
(packages/components/src/angle-picker-control
) @ciampo #45820Animate
(packages/components/src/animate
) #49243Animation
(packages/components/src/animation
)Autocomplete
(packages/components/src/autocomplete
) #47751BaseControl
(packages/components/src/base-control
) #39468BaseField
(packages/components/src/base-field
) #45712BorderBoxControl
(packages/components/src/border-box-control
) (Storybook #45002, tests #47755)BorderControl
(packages/components/src/border-control
) #41843BoxControl
(packages/components/src/box-control
) #47622Button
(packages/components/src/button
) #46997NavigatorBackButton
andNavigatorButton
) #47754ButtonGroup
(packages/components/src/button-group
) #41007Card
(packages/components/src/card
) #42941CheckboxControl
(packages/components/src/checkbox-control
) #40915CircularOptionPicker
(packages/components/src/circular-option-picker
) #47937ClipboardButton
(packages/components/src/clipboard-button
) #51334ColorIndicator
(packages/components/src/color-indicator
) #41587ColorListPicker
(packages/components/src/color-list-picker
) #46358ColorPalette
(packages/components/src/color-palette
) #44632ColorPicker
(packages/components/src/color-picker
) @chad1008 #49214ComboboxControl
(packages/components/src/combobox-control
) #47581Composite
(packages/components/src/composite
) #54028ConfirmDialog
(packages/components/src/confirm-dialog
) #54954CustomGradientPicker
(packages/components/src/custom-gradient-picker
) #48929CustomSelectControl
(packages/components/src/custom-select-control
) (instead of a refactor, the component will be rewritten from scratch https://github.com/WordPress/gutenberg/pull/41726)Dashicon
(packages/components/src/dashicon
) #45924DateTime
(packages/components/src/date-time
) #40775 #40986 #40957DimensionControl
(packages/components/src/dimension-control
) #47351Disabled
(packages/components/src/disabled
) #42708Disclosure
(packages/components/src/disclosure
) (will be migrated as part of the reakit -> ariakit refactor) #55639Divider
(packages/components/src/divider
) #41991Draggable
(packages/components/src/draggable
) #45471DropZone
(packages/components/src/drop-zone
) #43962Dropdown
(packages/components/src/dropdown
) (should also replace types inColorPalette
) #45787DropdownMenu
(packages/components/src/dropdown-menu
) (suggested in this comment) @chad1008 https://github.com/WordPress/gutenberg/pull/50187DuotonePicker
,DuotoneSwatch
(packages/components/src/duotone-picker
) #49060Elevation
(packages/components/src/elevation
) #42302ExternalLink
(packages/components/src/external-link
) #41681Flex
(packages/components/src/flex
) #42537FocalPointPicker
(packages/components/src/focal-point-picker
) #43872FocusableIframe
(packages/components/src/focusable-iframe
) #53979FontSizePicker
(packages/components/src/font-size-picker
) #44449FormFileUpload
(packages/components/src/form-file-upload
) #43960FormToggle
(packages/components/src/form-toggle
) #41729FormTokenField
(packages/components/src/form-token-field
) #41216, #43442GradientPicker
(packages/components/src/gradient-picker
) #48316 @chad1008Grid
(packages/components/src/grid
) #41923Guide
(packages/components/src/guide
) #47493HStack
packages/components/src/h-stack
) #41580Heading
(packages/components/src/heading
) #41921HigherOrder
(packages/components/src/higher-order
)navigate-regions
#48632with-constrained-tabbing
#48162with-fallback-styles
#48720with-filters
#48721with-focus-outside
#53980 (also remove the@ts-expect-error
calls inComboboxControl
)with-focus-return
#48748with-notices
#49088with-spoken-messages
#48163Icon
(packages/components/src/icon
) - convert tests #49066InputControl
(packages/components/src/input-control
) #33696IsolatedEventContainer
#54316 (packages/components/src/isolated-event-container
)ItemGroup
(packages/components/src/item-group
) (#46945)KeyboardShortcuts
(packages/components/src/keyboard-shortcuts
) #47429MenuGroup
(packages/components/src/menu-group
) #36561 #45617MenuItem
(packages/components/src/menu-item
) #53132 #37020MenuItemsChoice
(packages/components/src/menu-items-choice
) #47180Modal
(packages/components/src/modal
) #42949NavigableContainer
(packages/components/src/navigable-container
) #49377Navigation
(packages/components/src/navigation
) #48742Navigator
(packages/components/src/navigator
) (unit tests: #44970, storybook: #44979)Notice
(packages/components/src/notice
) #47118NumberControl
(packages/components/src/number-control
) (suggested in this comment) (include also changes proposed in https://github.com/WordPress/gutenberg/pull/37164#issuecomment-1031959395)value
prop and remove the last@ts-expect-error
commentsPaletteEdit
(packages/components/src/palette-edit
): #47764Panel
(packages/components/src/panel
) #47259Placeholder
(packages/components/src/placeholder
) #42990 #43069Popover
(packages/components/src/popover
) #43823 #44373QueryControl
(packages/components/src/query-controls
) #46721Radio
(packages/components/src/radio
)~RadioContext
(packages/components/src/radio-context
)~RadioControl
(packages/components/src/radio-control
) #41568RadioGroup
(packages/components/src/radio-group
)~RangeControl
(packages/components/src/range-control
) (suggested in this comment) https://github.com/WordPress/gutenberg/pull/40535, #41444, #41445ResizableBox
(packages/components/src/resizable-box
) (#46774, #47756)ResponsiveWrapper
(packages/components/src/responsive-wrapper
) #46480Sandbox
(packages/components/src/sandbox
) #46478ScrollLock
(packages/components/src/scroll-lock
) #42303Scrollable
(packages/components/src/scrollable
) #42016SearchControl
(packages/components/src/search-control
) #43871SelectControl
(packages/components/src/select-control
) #40737value
prop (string[]
ifmultiple
istrue
,string
otherwise) https://github.com/WordPress/gutenberg/pull/47390Shortcut
(packages/components/src/shortcut
) #42272SlotFill
(packages/components/src/slot-fill
) #51350Snackbar
(packages/components/src/snackbar
) (#45472)Spacer
(packages/components/src/spacer
) #42013Spinner
(packages/components/src/spinner
) #41540StyleProvider
(packages/components/src/style-provider
) #42541Surface
(packages/components/src/surface
) #41212Swatch
(packages/components/src/swatch
) #42162TabPanel
(packages/components/src/tab-panel
) #43536Text
(packages/components/src/text
) (check truncate behaviors noted in this comment, try removing boolean types fromadjustLineHeightForInnerControls
) #54953TextControl
(packages/components/src/text-control
) #40633TextHighlight
(packages/components/src/text-highlight
) #41698TextareaControl
(packages/components/src/textarea-control
) #41215Tip
(packages/components/src/tip
) #42262ToggleControl
(packages/components/src/toggle-control
) #43717ToggleGroupControl
(packages/components/src/toggle-group-control
)Toolbar
:Toolbar
(packages/components/src/toolbar
) #47087ToolbarButton
(packages/components/src/toolbar-button
) #47750ToolbarContext
(packages/components/src/toolbar-context
) #49002ToolbarDropdownMenu
(packages/components/src/toolbar-dropdown-menu
) #54321ToolbarGroup
(packages/components/src/toolbar-group
) #54317ToolbarItem
(packages/components/src/toolbar-item
) #49190ToolsPanel
(packages/components/src/tools-panel
) @ciampo (Storybook: #47944, Unit tests: #48275)Tooltip
(packages/components/src/tooltip
) (As per #42753, the component won't be refactored, but will be instead completely rewritten) #48440TreeGrid
(packages/components/src/tree-grid
) #47516TreeSelect
(packages/components/src/tree-select
) #41536Truncate
(packages/components/src/truncate
) #41697UnitControl
(packages/components/src/unit-control
) (refactored to TS in 35281, suggested follow ups in this comment, tests refactored in #40697)VStack
(packages/components/src/v-stack
) #41850View
(packages/components/src/view
) https://github.com/WordPress/gutenberg/pull/45667VisuallyHidden
(packages/components/src/visually-hidden
) #42220ZStack
(packages/components/src/z-stack
) #41694index.js
Click to reveal the dependency graph
![dependencygraph](https://user-images.githubusercontent.com/1083581/150875105-2f977303-ec51-4b45-aeae-e49d0c3418b8.svg)