diff --git a/packages/compose/README.md b/packages/compose/README.md
index 6d196235cbd5ed..98909cda14a03d 100644
--- a/packages/compose/README.md
+++ b/packages/compose/README.md
@@ -536,11 +536,11 @@ via props.
_Parameters_
-- _initialState_ `?Object`: Optional initial state of the component.
+- _initialState_ `TStateProps`: Optional initial state of the component.
_Returns_
-- `WPComponent`: Wrapped component.
+- `HigherOrderComponent< TProps & TStateProps & { setState: Component[ 'setState' ]; }, TProps >`: A higher order component wrapper accepting a component that takes the state props + its own props + `setState` and returning a component that only accepts the own props.
diff --git a/packages/compose/src/higher-order/with-state/index.js b/packages/compose/src/higher-order/with-state/index.js
deleted file mode 100644
index 02db9392b39631..00000000000000
--- a/packages/compose/src/higher-order/with-state/index.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * WordPress dependencies
- */
-import { Component } from '@wordpress/element';
-
-/**
- * Internal dependencies
- */
-import createHigherOrderComponent from '../../utils/create-higher-order-component';
-
-/**
- * A Higher Order Component used to provide and manage internal component state
- * via props.
- *
- * @param {?Object} initialState Optional initial state of the component.
- *
- * @return {WPComponent} Wrapped component.
- */
-export default function withState( initialState = {} ) {
- return createHigherOrderComponent( ( OriginalComponent ) => {
- return class WrappedComponent extends Component {
- constructor() {
- super( ...arguments );
-
- this.setState = this.setState.bind( this );
-
- this.state = initialState;
- }
-
- render() {
- return (
-
- );
- }
- };
- }, 'withState' );
-}
diff --git a/packages/compose/src/higher-order/with-state/index.tsx b/packages/compose/src/higher-order/with-state/index.tsx
new file mode 100644
index 00000000000000..5c83eef967aacc
--- /dev/null
+++ b/packages/compose/src/higher-order/with-state/index.tsx
@@ -0,0 +1,76 @@
+/**
+ * External dependencies
+ */
+// eslint-disable-next-line no-restricted-imports
+import type { ComponentType } from 'react';
+
+/**
+ * WordPress dependencies
+ */
+import { Component } from '@wordpress/element';
+
+/**
+ * Internal dependencies
+ */
+import createHigherOrderComponent from '../../utils/create-higher-order-component';
+// eslint-disable-next-line no-duplicate-imports
+import type { HigherOrderComponent } from '../../utils/create-higher-order-component';
+
+/**
+ * A Higher Order Component used to provide and manage internal component state
+ * via props.
+ *
+ * @param initialState Optional initial state of the component.
+ *
+ * @return A higher order component wrapper accepting a component that takes the state props + its own props + `setState` and returning a component that only accepts the own props.
+ */
+export default function withState<
+ TProps extends object,
+ TStateProps extends object
+>(
+ initialState: TStateProps = {} as TStateProps
+): HigherOrderComponent<
+ TProps &
+ TStateProps & {
+ setState: Component< TProps, TStateProps >[ 'setState' ];
+ },
+ TProps
+> {
+ return createHigherOrderComponent(
+ (
+ OriginalComponent: ComponentType<
+ TProps &
+ TStateProps & {
+ setState: Component<
+ TProps,
+ TStateProps
+ >[ 'setState' ];
+ }
+ >
+ ) => {
+ return class WrappedComponent extends Component<
+ TProps,
+ TStateProps
+ > {
+ constructor( props: any ) {
+ super( props );
+
+ this.setState = this.setState.bind( this );
+
+ this.state = initialState;
+ }
+
+ render() {
+ return (
+
+ );
+ }
+ };
+ },
+ 'withState'
+ );
+}
diff --git a/packages/compose/tsconfig.json b/packages/compose/tsconfig.json
index 9654eb9152302b..796acba0d08118 100644
--- a/packages/compose/tsconfig.json
+++ b/packages/compose/tsconfig.json
@@ -16,6 +16,7 @@
"src/higher-order/pure/**/*",
"src/higher-order/with-instance-id/**/*",
"src/higher-order/with-global-events/**/*",
+ "src/higher-order/with-state/**/*",
"src/hooks/use-async-list/**/*",
"src/hooks/use-constrained-tabbing/**/*",
"src/hooks/use-debounce/**/*",