diff --git a/.changeset/polymorphic-as-types.md b/.changeset/polymorphic-as-types.md
new file mode 100644
index 000000000..4f1c84bd9
--- /dev/null
+++ b/.changeset/polymorphic-as-types.md
@@ -0,0 +1,5 @@
+---
+"@linaria/react": patch
+---
+
+Add typing for intrinsic props selected through the polymorphic `as` prop on styled components.
diff --git a/packages/react/__dtslint__/styled-jsx.tsx b/packages/react/__dtslint__/styled-jsx.tsx
new file mode 100644
index 000000000..2662c71d8
--- /dev/null
+++ b/packages/react/__dtslint__/styled-jsx.tsx
@@ -0,0 +1,9 @@
+import * as React from 'react';
+
+import { styled } from '..';
+
+const Button = styled.button``;
+
+;
+// @ts-expect-error href requires an anchor-like target
+;
diff --git a/packages/react/__dtslint__/styled.ts b/packages/react/__dtslint__/styled.ts
index 52655b6ae..c94413037 100644
--- a/packages/react/__dtslint__/styled.ts
+++ b/packages/react/__dtslint__/styled.ts
@@ -27,6 +27,12 @@ const StyledDiv = styled.div``;
// $ExpectType "extends"
isExtends>>();
+const StyledButton = styled.button``;
+StyledButton({ as: 'a', href: '/' });
+StyledButton.defaultProps = { as: 'a' };
+// @ts-expect-error href requires an anchor-like target
+StyledButton({ href: '/' });
+
const A = (): React.ReactElement => React.createElement('div', null);
// @ts-expect-error
styled(A)``;
diff --git a/packages/react/__dtslint__/tsconfig.json b/packages/react/__dtslint__/tsconfig.json
index 3434572ac..ace06029a 100644
--- a/packages/react/__dtslint__/tsconfig.json
+++ b/packages/react/__dtslint__/tsconfig.json
@@ -1,6 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
+ "jsx": "react",
"lib": ["es6"],
"target": "ES2015",
"esModuleInterop": true,
diff --git a/packages/react/src/styled.ts b/packages/react/src/styled.ts
index fb0ee9a75..9d929bde9 100644
--- a/packages/react/src/styled.ts
+++ b/packages/react/src/styled.ts
@@ -260,10 +260,36 @@ function styled(tag: any): any {
};
}
+type FunctionComponentStatic<
+ TProps,
+ TKey extends PropertyKey,
+> = TKey extends keyof React.FunctionComponent
+ ? React.FunctionComponent[TKey]
+ : never;
+
+type StyledComponentWithAs = {
+ (
+ props: TProps & { as: TAs } & IntrinsicElements[TAs],
+ context?: any
+ ): ReturnType;
+ (
+ props: TProps & { as?: React.ElementType },
+ context?: any
+ ): ReturnType>;
+ contextTypes?: FunctionComponentStatic;
+ defaultProps?: FunctionComponentStatic<
+ TProps & { as?: React.ElementType },
+ 'defaultProps'
+ >;
+ displayName?: FunctionComponentStatic;
+ propTypes?: FunctionComponentStatic<
+ TProps & { as?: React.ElementType },
+ 'propTypes'
+ >;
+};
+
export type StyledComponent = WYWEvalMeta &
- ([T] extends [React.FunctionComponent]
- ? T
- : React.FunctionComponent);
+ ([T] extends [React.FunctionComponent] ? T : StyledComponentWithAs);
type StaticPlaceholder = string | number | CSSProperties | WYWEvalMeta;