Codemod to convert React PropTypes to TypeScript types.
- Supports function and class components
- Supports
static propTypes
declarations on class components - Supports files with multiple components
- Copies JSDoc comments to the generated TypeScript types
- Option to remove or preserve PropTypes after converting to TS
Run the following command with a file glob that matches the files you want to convert.
npx jscodeshift -t https://mskelton.dev/ratchet.ts GLOB
# Example
npx jscodeshift -t https://mskelton.dev/ratchet.ts src/**/*.{js,jsx}
In addition to the CLI, you can use Ratchet online at mskelton.dev/ratchet! Simply paste your input on the left and instantly see the output on the right!
// Input
import PropTypes from "prop-types"
import React from "react"
export function MyComponent(props) {
return <span />
}
MyComponent.propTypes = {
bar: PropTypes.string.isRequired,
foo: PropTypes.number,
}
// Output
import React from "react"
interface MyComponentProps {
bar: string
foo?: number
}
export function MyComponent(props: MyComponentProps) {
return <span />
}
Preserves prop types after converting to TS. There are two available modes:
all
and unconverted
.
CLI alias: --preserve-prop-types
This option will preserve all PropTypes. This is useful for component libraries where you support both TypeScript declarations and PropTypes.
Input:
import PropTypes from "prop-types"
import React from "react"
export function MyComponent(props) {
return <span />
}
MyComponent.propTypes = {
foo: PropTypes.number,
}
Output:
import PropTypes from "prop-types"
import React from "react"
interface MyComponentProps {
foo?: number
}
export function MyComponent(props: MyComponentProps) {
return <span />
}
MyComponent.propTypes = {
foo: PropTypes.number,
}
This option will preserve prop types which could not be fully converted. For
example, spread expressions are not converted, and custom validators are
converted to unknown
. This option is useful to preserve these expressions so
you can manually review and convert to their TypeScript equivalent.
Input:
import PropTypes from "prop-types"
import React from "react"
export function MyComponent(props) {
return <span />
}
MyComponent.propTypes = {
...OtherComponent.propTypes,
foo: PropTypes.number,
bar(props, propName, componentName) {
return new Error("Invalid prop")
},
}
Output:
import PropTypes from "prop-types"
import React from "react"
interface MyComponentProps {
foo?: number
bar: unknown
}
export function MyComponent(props: MyComponentProps) {
return <span />
}
MyComponent.propTypes = {
...OtherComponent.propTypes,
bar(props, propName, componentName) {
return new Error("Invalid prop")
},
}