• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/// <reference path="/.lib/react16.d.ts" />
2import * as React from "react";
3
4interface REACT_STATICS {
5    childContextTypes: true;
6    contextType: true;
7    contextTypes: true;
8    defaultProps: true;
9    displayName: true;
10    getDefaultProps: true;
11    getDerivedStateFromError: true;
12    getDerivedStateFromProps: true;
13    mixins: true;
14    propTypes: true;
15    type: true;
16}
17
18interface KNOWN_STATICS {
19    name: true;
20    length: true;
21    prototype: true;
22    caller: true;
23    callee: true;
24    arguments: true;
25    arity: true;
26}
27
28interface MEMO_STATICS {
29    '$$typeof': true;
30    compare: true;
31    defaultProps: true;
32    displayName: true;
33    propTypes: true;
34    type: true;
35}
36
37interface FORWARD_REF_STATICS {
38    '$$typeof': true;
39    render: true;
40    defaultProps: true;
41    displayName: true;
42    propTypes: true;
43}
44
45
46type NonReactStatics<
47    S extends React.ComponentType<any>,
48    C extends {
49        [key: string]: true
50    } = {}
51    > = {
52        [key in Exclude<
53            keyof S,
54            S extends React.MemoExoticComponent<any>
55            ? keyof MEMO_STATICS | keyof C
56            : S extends React.ForwardRefExoticComponent<any>
57            ? keyof FORWARD_REF_STATICS | keyof C
58            : keyof REACT_STATICS | keyof KNOWN_STATICS | keyof C
59        >]: S[key]
60    };
61
62export type AnyStyledComponent = StyledComponent<any, any, any, any> | StyledComponent<any, any, any>;
63export type StyledComponent<
64    C extends keyof JSX.IntrinsicElements | React.ComponentType<any>,
65    T extends object,
66    O extends object = {},
67    A extends keyof any = never
68    > = // the "string" allows this to be used as an object key
69    // I really want to avoid this if possible but it's the only way to use nesting with object styles...
70    string &
71    StyledComponentBase<C, T, O, A> &
72    NonReactStatics<C extends React.ComponentType<any> ? C : never>;
73
74export type StyledComponentProps<
75    // The Component from whose props are derived
76    C extends string | React.ComponentType<any>,
77    // The Theme from the current context
78    T extends object,
79    // The other props added by the template
80    O extends object,
81    // The props that are made optional by .attrs
82    A extends keyof any
83    > =
84    // Distribute O if O is a union type
85    O extends object
86    ? WithOptionalTheme<
87        Omit<
88            ReactDefaultizedProps<
89                C,
90                React.ComponentPropsWithRef<
91                    C extends IntrinsicElementsKeys | React.ComponentType<any> ? C : never
92                >
93            > &
94            O,
95            A
96        > &
97        Partial<
98            Pick<
99                React.ComponentPropsWithRef<
100                    C extends IntrinsicElementsKeys | React.ComponentType<any> ? C : never
101                > &
102                O,
103                A
104            >
105        >,
106        T
107    > &
108    WithChildrenIfReactComponentClass<C>
109    : never;
110
111type Defaultize<P, D> = P extends any
112    ? string extends keyof P
113    ? P
114    : Pick<P, Exclude<keyof P, keyof D>> &
115    Partial<Pick<P, Extract<keyof P, keyof D>>> &
116    Partial<Pick<D, Exclude<keyof D, keyof P>>>
117    : never;
118
119type ReactDefaultizedProps<C, P> = C extends { defaultProps: infer D } ? Defaultize<P, D> : P;
120
121type WithChildrenIfReactComponentClass<C extends string | React.ComponentType<any>> = C extends React.ComponentClass<
122    any
123>
124    ? { children?: React.ReactNode }
125    : {};
126export type IntrinsicElementsKeys = keyof JSX.IntrinsicElements;
127type WithOptionalTheme<P extends { theme?: T }, T> = Omit<P, 'theme'> & {
128    theme?: T;
129};
130
131type ForwardRefExoticBase<P> = Pick<React.ForwardRefExoticComponent<P>, keyof React.ForwardRefExoticComponent<any>>;
132
133type StyledComponentPropsWithAs<
134    C extends string | React.ComponentType<any>,
135    T extends object,
136    O extends object,
137    A extends keyof any,
138    F extends string | React.ComponentType<any> = C
139    > = StyledComponentProps<C, T, O, A> & { as?: C; forwardedAs?: F };
140
141export type StyledComponentInnerOtherProps<C extends AnyStyledComponent> = C extends StyledComponent<
142    any,
143    any,
144    infer O,
145    any
146>
147    ? O
148    : C extends StyledComponent<any, any, infer O>
149    ? O
150    : never;
151export type StyledComponentInnerAttrs<C extends AnyStyledComponent> = C extends StyledComponent<any, any, any, infer A>
152    ? A
153    : never;
154
155export interface StyledComponentBase<
156    C extends string | React.ComponentType<any>,
157    T extends object,
158    O extends object = {},
159    A extends keyof any = never
160    > extends ForwardRefExoticBase<StyledComponentProps<C, T, O, A>> {
161    // add our own fake call signature to implement the polymorphic 'as' prop
162    (props: StyledComponentProps<C, T, O, A> & { as?: never; forwardedAs?: never }): React.ReactElement<
163        StyledComponentProps<C, T, O, A>
164    >;
165    <AsC extends string | React.ComponentType<any> = C, FAsC extends string | React.ComponentType<any> = AsC>(
166        props: StyledComponentPropsWithAs<AsC, T, O, A, FAsC>,
167    ): React.ReactElement<StyledComponentPropsWithAs<AsC, T, O, A, FAsC>>;
168
169    withComponent<WithC extends AnyStyledComponent>(
170        component: WithC,
171    ): StyledComponent<
172        StyledComponentInnerComponent<WithC>,
173        T,
174        O & StyledComponentInnerOtherProps<WithC>,
175        A | StyledComponentInnerAttrs<WithC>
176    >;
177    withComponent<WithC extends keyof JSX.IntrinsicElements | React.ComponentType<any>>(
178        component: WithC,
179    ): StyledComponent<WithC, T, O, A>;
180}
181
182export type StyledComponentInnerComponent<C extends React.ComponentType<any>> = C extends StyledComponent<
183    infer I,
184    any,
185    any,
186    any
187>
188    ? I
189    : C extends StyledComponent<infer I, any, any>
190    ? I
191    : C;
192export type StyledComponentPropsWithRef<
193    C extends keyof JSX.IntrinsicElements | React.ComponentType<any>
194    > = C extends AnyStyledComponent
195    ? React.ComponentPropsWithRef<StyledComponentInnerComponent<C>> // shouldn't have an instantiation limit error
196    : React.ComponentPropsWithRef<C>;