UNPKG

5.15 kBTypeScriptView Raw
1// TypeScript Version: 3.0
2
3// changed from: https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/styled-components
4
5import * as React from 'react';
6
7type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
8
9// Any prop that has a default prop becomes optional, but its type is unchanged
10// Undeclared default props are augmented into the resulting allowable attributes
11// If declared props have indexed properties, ignore default props entirely as keyof gets widened
12// Wrap in an outer-level conditional type to allow distribution over props that are unions
13type Defaultize<P, D> = P extends any
14 ? string extends keyof P
15 ? P
16 : Pick<P, Exclude<keyof P, keyof D>> &
17 Partial<Pick<P, Extract<keyof P, keyof D>>> &
18 Partial<Pick<D, Exclude<keyof D, keyof P>>>
19 : never;
20
21type ReactDefaultizedProps<C, P> = C extends { defaultProps: infer D }
22 ? Defaultize<P, D>
23 : P;
24
25export type StyledComponentProps<
26 // The Component from whose props are derived
27 C extends keyof JSX.IntrinsicElements | React.ComponentType<any>,
28 // The other props added by the template
29 O extends object,
30 // The props that are made optional by .attrs
31 A extends keyof any
32> = Omit<ReactDefaultizedProps<C, React.ComponentPropsWithRef<C>> & O, A> &
33 Partial<Pick<React.ComponentPropsWithRef<C> & O, A>> &
34 WithChildrenIfReactComponentClass<C>;
35
36// Because of React typing quirks, when getting props from a React.ComponentClass,
37// we need to manually add a `children` field.
38// See https://github.com/DefinitelyTyped/DefinitelyTyped/pull/31945
39// and https://github.com/DefinitelyTyped/DefinitelyTyped/pull/32843
40type WithChildrenIfReactComponentClass<
41 C extends keyof JSX.IntrinsicElements | React.ComponentType<any>
42> = C extends React.ComponentClass<any> ? { children?: React.ReactNode } : {};
43
44type StyledComponentPropsWithAs<
45 C extends keyof JSX.IntrinsicElements | React.ComponentType<any>,
46 O extends object,
47 A extends keyof any
48> = StyledComponentProps<C, O, A> & { as?: C };
49
50// abuse Pick to strip the call signature from ForwardRefExoticComponent
51type ForwardRefExoticBase<P> = Pick<
52 React.ForwardRefExoticComponent<P>,
53 keyof React.ForwardRefExoticComponent<any>
54>;
55
56export interface StyledComponent<
57 C extends keyof JSX.IntrinsicElements | React.ComponentType<any>,
58 O extends object = {},
59 A extends keyof any = never
60> extends ForwardRefExoticBase<StyledComponentProps<C, O, A>> {
61 // add our own fake call signature to implement the polymorphic 'as' prop
62 // NOTE: TS <3.2 will refuse to infer the generic and this component becomes impossible to use in JSX
63 // just the presence of the overload is enough to break JSX
64 //
65 // TODO (TypeScript 3.2): actually makes the 'as' prop polymorphic
66 (props: StyledComponentProps<C, O, A> & { as?: never }): React.ReactElement<
67 StyledComponentProps<C, O, A>
68 >;
69 <AsC extends keyof JSX.IntrinsicElements | React.ComponentType<any> = C>(
70 props: StyledComponentPropsWithAs<AsC, O, A>,
71 ): React.ReactElement<StyledComponentPropsWithAs<AsC, O, A>>;
72
73 withComponent<
74 WithC extends keyof JSX.IntrinsicElements | React.ComponentType<any>
75 >(
76 component: WithC,
77 ): StyledComponent<WithC, O>;
78}
79
80export type StyledComponentPropsWithRef<
81 C extends keyof JSX.IntrinsicElements | React.ComponentType<any>
82> = React.ComponentPropsWithRef<C>;
83
84type Attrs<P, A extends Partial<P>> = ((props: P) => A) | A;
85
86export interface StyledFunction<
87 C extends keyof JSX.IntrinsicElements | React.ComponentType<any>,
88 O extends object = {},
89 A extends keyof any = never
90> {
91 (...rest: any[]): StyledComponent<C, O, A>;
92 // tslint:disable-next-line:no-unnecessary-generics
93 <U extends object>(...rest: any[]): StyledComponent<C, O & U, A>;
94
95 attrs<
96 U extends object,
97 NewA extends Partial<StyledComponentPropsWithRef<C> & U> & {
98 [others: string]: any;
99 } = Partial<StyledComponentPropsWithRef<C> & U>
100 >(
101 provideProps: Attrs<
102 ReactDefaultizedProps<C, React.ComponentPropsWithRef<C>> & U,
103 NewA
104 >,
105 ): StyledFunction<C, O & NewA, A | keyof NewA>;
106}
107
108export type StyledTags = {
109 readonly [TTag in keyof JSX.IntrinsicElements]: StyledFunction<TTag>;
110};
111
112export interface StyledOptions {
113 allowAs?: boolean;
114}
115
116export type mapper<TInner, TOuter> = (input: TInner) => TOuter;
117
118export interface CreateStyled extends StyledTags {
119 <C extends keyof JSX.IntrinsicElements | React.ComponentType<any>>(
120 component: C,
121 options?: StyledOptions,
122 ): StyledFunction<C>;
123
124 <
125 C extends keyof JSX.IntrinsicElements | React.ComponentType<any>,
126 OtherProps extends object
127 >(
128 component: C,
129 options?: StyledOptions,
130 ): StyledFunction<C, OtherProps>; // tslint:disable-line:no-unnecessary-generics
131}
132
133declare const styled: CreateStyled;
134
135export function css(
136 template: TemplateStringsArray,
137 ...args: any[]
138): Record<string, string>;
139
140export default styled;
141
142declare module 'react' {
143 interface DOMAttributes<T> {
144 css?: string | Record<string, string>;
145 }
146}
147
148declare global {
149 namespace JSX {
150 interface IntrinsicAttributes {
151 css?: string | Record<string, string>;
152 }
153 }
154}