Skip to content

Instantly share code, notes, and snippets.

@nfarina
Last active July 11, 2022 18:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save nfarina/ea282fbb01574e95d87ce661f7fe8630 to your computer and use it in GitHub Desktop.
Save nfarina/ea282fbb01574e95d87ce661f7fe8630 to your computer and use it in GitHub Desktop.
/**
* A "fast" version of @types/styled-components that does not impact the
* performance of the TypeScript language service (which is directly related to
* the performance of VSCode).
*
* NOTE: This implements only a fraction of the features provided by the
* @types/styled-component package. Notably, it does not support typing the
* "props" parameter when interpolating within template strings. If someone
* knows how to type that without impacting performance, please let me know!
*/
declare module "styled-components" {
export interface StyledInterface extends StyledComponentFactories {
<C extends React.ComponentType<any>>(component: C): StyledFunction<C>;
}
export type StyledComponentFactories = {
[TTag in keyof JSX.IntrinsicElements]: StyledFunction<TTag>;
};
export interface StyledFunction<
C extends keyof JSX.IntrinsicElements | React.ComponentType<any>,
> {
<O extends object = {}>(
first: TemplateStringsArray,
...rest: Array<any>
): StyledComponent<C, O>;
attrs<O extends object = {}>(
props:
| Partial<React.ComponentProps<C>>
| ((props: any) => Partial<React.ComponentProps<C>>),
): StyledFunction<C, O>;
}
export interface StyledComponent<
C extends keyof JSX.IntrinsicElements | React.ComponentType<any>,
O extends object = {},
> {
(
props: React.ComponentProps<C> & {
as?: string | React.ComponentType<any>;
} & O,
): React.ReactElement<React.ComponentProps<C> & O>;
}
export function createGlobalStyle<O extends object = {}>(
first: TemplateStringsArray,
...rest: any[]
): StyledComponent<"div", O>;
export function css(first: TemplateStringsArray, ...rest: any[]): string;
export function keyframes(
first: TemplateStringsArray,
...rest: any[]
): string;
export const ThemeProvider: StyledComponent<any>;
export const ThemeContext: React.Context<any>;
export class ServerStyleSheet {
constructor();
collectStyles(element: React.ReactElement<any>): React.ReactElement<any>;
getStyleTags(): string;
seal(): void;
}
declare const styled: StyledInterface;
export default styled;
}
@karlvr
Copy link

karlvr commented Nov 22, 2021

@nfarina thank you for this! It might just save our sanity.

We seem to have improved the typing on props in our use-case, at least:

	type StyledFunctionTemplateArgumentResult = string | undefined | boolean | number

	type StyledFunctionTemplateArgument<O extends object> =
	StyledFunctionTemplateArgumentResult | ((props: O & { theme: any }) => StyledFunctionTemplateArgumentResult)

	export interface StyledFunction<
		C extends keyof JSX.IntrinsicElements | React.ComponentType<any>,
	> {
		<O extends object = {}>(
			first: TemplateStringsArray,
			...rest: Array<StyledFunctionTemplateArgument<O>>
		): StyledComponent<C, O>

I'm not sure it's complete, but it's working at the moment for us.

@nfarina
Copy link
Author

nfarina commented Nov 28, 2021

@karlvr Thanks so much for giving that a shot! For our codebase, pasting that results in 300+ compiler errors - it seems like it causes all styled components to require props from unrelated components. I haven't dug into it too much yet though.

@finnp
Copy link

finnp commented Jan 27, 2022

Awesome! I saw this but ended up writing my own types from scratch to get a better grasp of it and because I needed it for React Native.

I published the React Native version of the types here: https://github.com/karugamo/faster-styled-components-types

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment