diff --git a/.changeset/funny-pots-explain.md b/.changeset/funny-pots-explain.md
new file mode 100644
index 00000000000..4791170c256
--- /dev/null
+++ b/.changeset/funny-pots-explain.md
@@ -0,0 +1,5 @@
+---
+"@primer/components": patch
+---
+
+Migrate `StyledOcticon` to TypeScript
diff --git a/src/StyledOcticon.js b/src/StyledOcticon.js
deleted file mode 100644
index 3138ddf69a7..00000000000
--- a/src/StyledOcticon.js
+++ /dev/null
@@ -1,31 +0,0 @@
-import React from 'react'
-import PropTypes from 'prop-types'
-import styled from 'styled-components'
-import {COMMON} from './constants'
-import theme from './theme'
-import sx from './sx'
-
-function IconWrapper({icon: IconComponent, className, ...rest}) {
- return
-}
-
-const StyledOcticon = styled(IconWrapper)`
- ${COMMON}
- ${sx}
-`
-
-StyledOcticon.defaultProps = {
- theme,
- size: 16
-}
-
-StyledOcticon.propTypes = {
- ...COMMON.propTypes,
- ...sx.propTypes,
- icon: PropTypes.elementType.isRequired,
- size: PropTypes.oneOfType([PropTypes.number, PropTypes.oneOf(['small', 'medium', 'large'])]),
- theme: PropTypes.object,
- verticalAlign: PropTypes.oneOf(['middle', 'text-bottom', 'text-top', 'top'])
-}
-
-export default StyledOcticon
diff --git a/src/StyledOcticon.tsx b/src/StyledOcticon.tsx
new file mode 100644
index 00000000000..36a4a2bd518
--- /dev/null
+++ b/src/StyledOcticon.tsx
@@ -0,0 +1,36 @@
+import React from 'react'
+import PropTypes from 'prop-types'
+import styled from 'styled-components'
+import {COMMON, SystemCommonProps} from './constants'
+import theme from './theme'
+import sx, {SxProp} from './sx'
+import {IconProps} from '@primer/octicons-react'
+import {ComponentProps} from './utils/types'
+
+type OcticonProps = {icon: React.ElementType} & IconProps
+
+function Octicon({icon: IconComponent, ...rest}: OcticonProps) {
+ return
+}
+
+const StyledOcticon = styled(Octicon)`
+ ${COMMON}
+ ${sx}
+`
+
+StyledOcticon.defaultProps = {
+ theme,
+ size: 16
+}
+
+StyledOcticon.propTypes = {
+ ...COMMON.propTypes,
+ ...sx.propTypes,
+ icon: PropTypes.any.isRequired,
+ size: PropTypes.any,
+ theme: PropTypes.object,
+ verticalAlign: PropTypes.oneOf(['middle', 'text-bottom', 'text-top', 'top'])
+}
+
+export type StyledOcticonProps = ComponentProps
+export default StyledOcticon
diff --git a/src/__tests__/StyledOcticon.js b/src/__tests__/StyledOcticon.tsx
similarity index 88%
rename from src/__tests__/StyledOcticon.js
rename to src/__tests__/StyledOcticon.tsx
index a29c4ffbdf9..fe63816ca21 100644
--- a/src/__tests__/StyledOcticon.js
+++ b/src/__tests__/StyledOcticon.tsx
@@ -15,10 +15,6 @@ describe('StyledOcticon', () => {
default: StyledOcticon
})
- it('implements system props', () => {
- expect(StyledOcticon).toImplementSystemProps(COMMON)
- })
-
it('should have no axe violations', async () => {
const {container} = HTMLRender()
const results = await axe(container)
diff --git a/src/__tests__/__snapshots__/StyledOcticon.js.snap b/src/__tests__/__snapshots__/StyledOcticon.tsx.snap
similarity index 100%
rename from src/__tests__/__snapshots__/StyledOcticon.js.snap
rename to src/__tests__/__snapshots__/StyledOcticon.tsx.snap