// Type definitions for styled-components 4.1 // Project: https://github.com/styled-components/styled-components, https://styled-components.com // Definitions by: Igor Oleinikov // Ihor Chulinda // Adam Lavin // Jessica Franco // Jason Killian // Sebastian Silbermann // David Ruisinger // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 2.9 // forward declarations declare global { namespace NodeJS { // tslint:disable-next-line:no-empty-interface interface ReadableStream {} } } import * as CSS from "csstype"; import * as React from "react"; export type CSSObject = CSS.Properties & // Index type to allow selector nesting // This is "[key in string]" and not "[key: string]" to allow CSSObject to be self-referential { // we need the CSS.Properties in here too to ensure the index signature doesn't create impossible values [key in string]: | CSS.Properties[keyof CSS.Properties< string | number >] | CSSObject }; export type CSSKeyframes = object & { [key: string]: CSSObject }; export interface ThemeProps { theme: T; } export type ThemedStyledProps = P & ThemeProps; export type StyledProps

= ThemedStyledProps>; // Any prop that has a default prop becomes optional, but its type is unchanged // Undeclared default props are augmented into the resulting allowable attributes // If declared props have indexed properties, ignore default props entirely as keyof gets widened // Wrap in an outer-level conditional type to allow distribution over props that are unions type Defaultize = P extends any ? string extends keyof P ? P : & PickU> & Partial>> & Partial>> : never; type ReactDefaultizedProps = C extends { defaultProps: infer D; } ? Defaultize : P; export type StyledComponentProps< // The Component from whose props are derived C extends keyof JSX.IntrinsicElements | React.ComponentType, // The Theme from the current context T extends object, // The other props added by the template O extends object, // The props that are made optional by .attrs A extends keyof any > = WithOptionalTheme< OmitU< ReactDefaultizedProps< C, React.ComponentPropsWithRef > & O, A > & Partial & O, A>>, T > & WithChildrenIfReactComponentClass; // Because of React typing quirks, when getting props from a React.ComponentClass, // we need to manually add a `children` field. // See https://github.com/DefinitelyTyped/DefinitelyTyped/pull/31945 // and https://github.com/DefinitelyTyped/DefinitelyTyped/pull/32843 type WithChildrenIfReactComponentClass< C extends keyof JSX.IntrinsicElements | React.ComponentType > = C extends React.ComponentClass ? { children?: React.ReactNode } : {}; type StyledComponentPropsWithAs< C extends keyof JSX.IntrinsicElements | React.ComponentType, T extends object, O extends object, A extends keyof any > = StyledComponentProps & { as?: C }; export type FalseyValue = undefined | null | false; export type Interpolation

= | InterpolationValue | FlattenInterpolation

| InterpolationFunction

; // must be an interface to be self-referential export interface FlattenInterpolation

extends ReadonlyArray> {} export type InterpolationValue = | string | number | FalseyValue | Keyframes | StyledComponentInterpolation | CSSObject; export type SimpleInterpolation = | InterpolationValue | FlattenSimpleInterpolation; // must be an interface to be self-referential export interface FlattenSimpleInterpolation extends ReadonlyArray {} export type InterpolationFunction

= (props: P) => Interpolation

; type Attrs, T> = | ((props: ThemedStyledProps) => A) | A; type DeprecatedAttrs, T> = { [K in keyof A]: ((props: ThemedStyledProps) => A[K]) | A[K] }; export type ThemedGlobalStyledClassProps = WithOptionalTheme & { suppressMultiMountWarning?: boolean; }; export interface GlobalStyleComponent extends React.ComponentClass> {} // remove the call signature from StyledComponent so Interpolation can still infer InterpolationFunction type StyledComponentInterpolation = | Pick< StyledComponentBase, keyof StyledComponentBase > | Pick< StyledComponentBase, keyof StyledComponentBase >; // abuse Pick to strip the call signature from ForwardRefExoticComponent type ForwardRefExoticBase

= Pick< React.ForwardRefExoticComponent

, keyof React.ForwardRefExoticComponent >; // extracts React defaultProps type ReactDefaultProps = C extends { defaultProps: infer D; } ? D : never; // any doesn't count as assignable to never in the extends clause, and we default A to never export type AnyStyledComponent = | StyledComponent | StyledComponent; export type StyledComponent< C extends keyof JSX.IntrinsicElements | React.ComponentType, T extends object, O extends object = {}, A extends keyof any = never > = // the "string" allows this to be used as an object key // I really want to avoid this if possible but it's the only way to use nesting with object styles... string & StyledComponentBase; export interface StyledComponentBase< C extends keyof JSX.IntrinsicElements | React.ComponentType, T extends object, O extends object = {}, A extends keyof any = never > extends ForwardRefExoticBase> { // add our own fake call signature to implement the polymorphic 'as' prop // NOTE: TS <3.2 will refuse to infer the generic and this component becomes impossible to use in JSX // just the presence of the overload is enough to break JSX // // TODO (TypeScript 3.2): actually makes the 'as' prop polymorphic // ( // props: StyledComponentProps & { as?: never } // ): React.ReactElement> // = C>( // props: StyledComponentPropsWithAs // ): React.ReactElement> // TODO (TypeScript 3.2): delete this overload ( props: StyledComponentProps & { /** * Typing Note: prefer using .withComponent for now as it is actually type-safe. * * String types need to be cast to themselves to become literal types (as={'a' as 'a'}). */ as?: keyof JSX.IntrinsicElements | React.ComponentType; } ): React.ReactElement>; withComponent( component: WithC ): StyledComponent< StyledComponentInnerComponent, T, O & StyledComponentInnerOtherProps, A | StyledComponentInnerAttrs >; withComponent< WithC extends keyof JSX.IntrinsicElements | React.ComponentType >( component: WithC ): StyledComponent; } export interface ThemedStyledFunctionBase< C extends keyof JSX.IntrinsicElements | React.ComponentType, T extends object, O extends object = {}, A extends keyof any = never > { ( first: | TemplateStringsArray | CSSObject | InterpolationFunction< ThemedStyledProps & O, T> >, ...rest: Array< Interpolation< ThemedStyledProps & O, T> > > ): StyledComponent; ( first: | TemplateStringsArray | CSSObject | InterpolationFunction< ThemedStyledProps & O & U, T> >, ...rest: Array< Interpolation< ThemedStyledProps & O & U, T> > > ): StyledComponent; } export interface ThemedStyledFunction< C extends keyof JSX.IntrinsicElements | React.ComponentType, T extends object, O extends object = {}, A extends keyof any = never > extends ThemedStyledFunctionBase { // Fun thing: 'attrs' can also provide a polymorphic 'as' prop // My head already hurts enough so maybe later... attrs< U, NewA extends Partial & U> & { [others: string]: any; } = {} >( attrs: Attrs & U, NewA, T> ): ThemedStyledFunction; // Only this overload is deprecated // tslint:disable:unified-signatures /** @deprecated Prefer using the new single function style, to be removed in v5 */ attrs< U, NewA extends Partial & U> & { [others: string]: any; } = {} >( attrs: DeprecatedAttrs & U, NewA, T> ): ThemedStyledFunction; // tslint:enable:unified-signatures } export type StyledFunction< C extends keyof JSX.IntrinsicElements | React.ComponentType > = ThemedStyledFunction; type ThemedStyledComponentFactories = { [TTag in keyof JSX.IntrinsicElements]: ThemedStyledFunction }; export type StyledComponentInnerComponent< C extends React.ComponentType > = C extends | StyledComponent | StyledComponent ? I : C; export type StyledComponentPropsWithRef< C extends keyof JSX.IntrinsicElements | React.ComponentType > = C extends AnyStyledComponent ? React.ComponentPropsWithRef> : React.ComponentPropsWithRef; export type StyledComponentInnerOtherProps = C extends | StyledComponent | StyledComponent ? O : never; export type StyledComponentInnerAttrs< C extends AnyStyledComponent > = C extends StyledComponent ? A : never; export interface ThemedBaseStyledInterface extends ThemedStyledComponentFactories { (component: C): ThemedStyledFunction< StyledComponentInnerComponent, T, StyledComponentInnerOtherProps, StyledComponentInnerAttrs >; >( // unfortunately using a conditional type to validate that it can receive a `theme?: Theme` // causes tests to fail in TS 3.1 component: C ): ThemedStyledFunction; } export type ThemedStyledInterface = ThemedBaseStyledInterface< AnyIfEmpty >; export type StyledInterface = ThemedStyledInterface; export interface BaseThemedCssFunction { ( first: TemplateStringsArray | CSSObject, ...interpolations: SimpleInterpolation[] ): FlattenSimpleInterpolation; ( first: | TemplateStringsArray | CSSObject | InterpolationFunction>, ...interpolations: Array>> ): FlattenInterpolation>;

( first: | TemplateStringsArray | CSSObject | InterpolationFunction>, ...interpolations: Array>> ): FlattenInterpolation>; } export type ThemedCssFunction = BaseThemedCssFunction< AnyIfEmpty >; // Helper type operators // Pick that distributes over union types export type PickU = T extends any ? {[P in K]: T[P]} : never; export type OmitU = T extends any ? PickU> : never; type WithOptionalTheme

= OmitU & { theme?: T; }; type AnyIfEmpty = keyof T extends never ? any : T; export interface ThemedStyledComponentsModule< T extends object, U extends object = T > { default: ThemedStyledInterface; css: ThemedCssFunction; // unfortunately keyframes can't interpolate props from the theme keyframes( strings: TemplateStringsArray | CSSKeyframes, ...interpolations: SimpleInterpolation[] ): Keyframes; createGlobalStyle

( first: | TemplateStringsArray | CSSObject | InterpolationFunction>, ...interpolations: Array>> ): GlobalStyleComponent; withTheme: WithThemeFnInterface; ThemeProvider: ThemeProviderComponent; ThemeConsumer: React.Consumer; ThemeContext: React.Context; // This could be made to assert `target is StyledComponent` instead, but that feels not type safe isStyledComponent: typeof isStyledComponent; ServerStyleSheet: typeof ServerStyleSheet; StyleSheetManager: typeof StyleSheetManager; } declare const styled: StyledInterface; export const css: ThemedCssFunction; export type BaseWithThemeFnInterface = < C extends React.ComponentType >( // this check is roundabout because the extends clause above would // not allow any component that accepts _more_ than theme as a prop component: React.ComponentProps extends { theme?: T } ? C : never ) => React.ForwardRefExoticComponent< WithOptionalTheme, T> >; export type WithThemeFnInterface = BaseWithThemeFnInterface< AnyIfEmpty >; export const withTheme: WithThemeFnInterface; /** * This interface can be augmented by users to add types to `styled-components`' default theme * without needing to reexport `ThemedStyledComponentsModule`. */ // Unfortunately, there is no way to write tests for this // as any augmentation will break the tests for the default case (not augmented). // tslint:disable-next-line:no-empty-interface export interface DefaultTheme {} export interface ThemeProviderProps { children?: React.ReactChild; // only one child is allowed, goes through React.Children.only theme: T | ((theme: U) => T); } export type BaseThemeProviderComponent< T extends object, U extends object = T > = React.ComponentClass>; export type ThemeProviderComponent< T extends object, U extends object = T > = BaseThemeProviderComponent, AnyIfEmpty>; export const ThemeProvider: ThemeProviderComponent>; // NOTE: this technically starts as undefined, but allowing undefined is unhelpful when used correctly export const ThemeContext: React.Context>; export const ThemeConsumer: typeof ThemeContext["Consumer"]; export interface Keyframes { getName(): string; } export function keyframes( strings: TemplateStringsArray | CSSKeyframes, ...interpolations: SimpleInterpolation[] ): Keyframes; export function createGlobalStyle

( first: | TemplateStringsArray | CSSObject | InterpolationFunction>, ...interpolations: Array>> ): GlobalStyleComponent; export function isStyledComponent( target: any ): target is StyledComponent; export class ServerStyleSheet { collectStyles( tree: React.ReactNode ): React.ReactElement<{ sheet: ServerStyleSheet }>; getStyleTags(): string; getStyleElement(): Array>; interleaveWithNodeStream( readableStream: NodeJS.ReadableStream ): NodeJS.ReadableStream; readonly instance: this; seal(): void; } type StyleSheetManagerProps = | { sheet: ServerStyleSheet; target?: never; } | { sheet?: never; target: HTMLElement; }; export class StyleSheetManager extends React.Component< StyleSheetManagerProps > {} /** * The CSS prop is not declared by default in the types as it would cause 'css' to be present * on the types of anything that uses styled-components indirectly, even if they do not use the * babel plugin. * * You can load a default declaration by using writing this special import from * a typescript file. This module does not exist in reality, which is why the {} is important: * * ```ts * import {} from 'styled-components/cssprop' * ``` * * Or you can declare your own module augmentation, which allows you to specify the type of Theme: * * ```ts * import { CSSProp } from 'styled-components' * * interface MyTheme {} * * declare module 'react' { * interface Attributes { * css?: CSSProp * } * } * ``` */ // ONLY string literals and inline invocations of css`` are supported, anything else crashes the plugin export type CSSProp> = | string | FlattenInterpolation>; export default styled;