mirror of
https://github.com/gosticks/DefinitelyTyped.git
synced 2026-07-09 19:50:08 +00:00
Merge pull request #33341 from flavordaaave/master
Added interface to re-export module with theme interface
This commit is contained in:
1
types/styled-components/index.d.ts
vendored
1
types/styled-components/index.d.ts
vendored
@@ -6,6 +6,7 @@
|
||||
// Jessica Franco <https://github.com/Jessidhia>
|
||||
// Jason Killian <https://github.com/jkillian>
|
||||
// Sebastian Silbermann <https://github.com/eps1lon>
|
||||
// David Ruisinger <https://github.com/flavordaaave>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
// TypeScript Version: 2.9
|
||||
|
||||
|
||||
31
types/styled-components/native.d.ts
vendored
31
types/styled-components/native.d.ts
vendored
@@ -2,24 +2,28 @@ import * as ReactNative from 'react-native';
|
||||
import * as React from 'react';
|
||||
|
||||
export {
|
||||
DefaultTheme,
|
||||
css,
|
||||
DefaultTheme,
|
||||
isStyledComponent,
|
||||
ThemeProps,
|
||||
ThemeProvider,
|
||||
ThemeConsumer,
|
||||
ThemeContext,
|
||||
ThemeProps,
|
||||
ThemeProvider,
|
||||
withTheme,
|
||||
} from './index';
|
||||
|
||||
import {
|
||||
AnyStyledComponent,
|
||||
DefaultTheme,
|
||||
isStyledComponent,
|
||||
StyledComponentInnerAttrs,
|
||||
StyledComponentInnerComponent,
|
||||
StyledComponentInnerOtherProps,
|
||||
StyledComponentInnerAttrs,
|
||||
ThemedCssFunction,
|
||||
ThemedStyledFunction,
|
||||
ThemedStyledInterface,
|
||||
DefaultTheme
|
||||
ThemeProviderComponent,
|
||||
WithThemeFnInterface
|
||||
} from './index';
|
||||
|
||||
type AnyIfEmpty<T extends object> = keyof T extends never ? any : T;
|
||||
@@ -211,6 +215,23 @@ export interface ReactNativeStyledInterface<T extends object> extends ReactNativ
|
||||
>;
|
||||
}
|
||||
|
||||
export interface ReactNativeThemedStyledComponentsModule<
|
||||
T extends object,
|
||||
U extends object = T
|
||||
> {
|
||||
default: ReactNativeStyledInterface<T>;
|
||||
|
||||
css: ThemedCssFunction<T>;
|
||||
|
||||
withTheme: WithThemeFnInterface<T>;
|
||||
ThemeProvider: ThemeProviderComponent<T, U>;
|
||||
ThemeConsumer: React.Consumer<T>;
|
||||
ThemeContext: React.Context<T>;
|
||||
|
||||
// This could be made to assert `target is StyledComponent<any, T>` instead, but that feels not type safe
|
||||
isStyledComponent: typeof isStyledComponent;
|
||||
}
|
||||
|
||||
declare const styled: ReactNativeStyledInterface<DefaultTheme>;
|
||||
|
||||
export default styled;
|
||||
|
||||
@@ -9,6 +9,7 @@ import styled, {
|
||||
ThemeProvider,
|
||||
withTheme,
|
||||
ThemeConsumer,
|
||||
ReactNativeThemedStyledComponentsModule,
|
||||
} from "styled-components/native";
|
||||
import {} from "styled-components/cssprop";
|
||||
|
||||
@@ -57,3 +58,141 @@ const TomatoButton = styled(MyButton)`
|
||||
|
||||
// needs name prop, but not theme prop
|
||||
const tomatoElement = <TomatoButton name="needed" />;
|
||||
|
||||
async function typedThemes() {
|
||||
const theme = {
|
||||
color: "green"
|
||||
};
|
||||
|
||||
// abuse "await import(...)" to be able to reference the styled-components namespace
|
||||
// without actually doing a top level namespace import
|
||||
const {
|
||||
default: styled,
|
||||
css,
|
||||
ThemeProvider,
|
||||
ThemeConsumer
|
||||
} = (await import("styled-components/native")) as any as ReactNativeThemedStyledComponentsModule<
|
||||
typeof theme
|
||||
>;
|
||||
|
||||
const ThemedView = styled.View`
|
||||
background: ${props => {
|
||||
// $ExpectType string
|
||||
props.theme.color;
|
||||
// $ExpectType string | undefined
|
||||
props.testID;
|
||||
return props.theme.color;
|
||||
}};
|
||||
`;
|
||||
const ThemedView2 = styled.View(props => {
|
||||
// $ExpectType string
|
||||
props.theme.color;
|
||||
// $ExpectType string | undefined
|
||||
props.testID;
|
||||
|
||||
return {
|
||||
background: props.theme.color
|
||||
};
|
||||
});
|
||||
const ThemedView3 = styled.View(props => {
|
||||
// $ExpectType string
|
||||
props.theme.color;
|
||||
// $ExpectType string | undefined
|
||||
props.testID;
|
||||
|
||||
return css`
|
||||
background: ${props.theme.color};
|
||||
`;
|
||||
});
|
||||
const themedCss = css`
|
||||
background: ${props => {
|
||||
// $ExpectType string
|
||||
props.theme.color;
|
||||
// $ExpectType "theme"
|
||||
type Keys = keyof typeof props;
|
||||
return props.theme.color;
|
||||
}};
|
||||
`;
|
||||
// can't use a FlattenInterpolation as the first argument, would make broken css
|
||||
// $ExpectError
|
||||
const ThemedView4 = styled.View(themedCss);
|
||||
|
||||
const themedCssWithNesting = css(props => ({
|
||||
color: props.theme.color,
|
||||
[ThemedView3]: {
|
||||
color: "green"
|
||||
}
|
||||
}));
|
||||
|
||||
return (
|
||||
<ThemeProvider theme={theme}>
|
||||
<>
|
||||
<ThemedView />
|
||||
<ThemedView2 />
|
||||
<ThemedView3 />
|
||||
<ThemeConsumer>
|
||||
{theme => {
|
||||
// $ExpectType string
|
||||
theme.color;
|
||||
return theme.color;
|
||||
}}
|
||||
</ThemeConsumer>
|
||||
</>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
|
||||
async function reexportCompatibility() {
|
||||
const sc = await import("styled-components/native");
|
||||
const themed = sc as ReactNativeThemedStyledComponentsModule<any>;
|
||||
|
||||
let { ...scExports } = sc;
|
||||
let { ...themedExports } = themed;
|
||||
// both branches must be assignable to each other
|
||||
if (Math.random()) {
|
||||
scExports = themedExports;
|
||||
} else {
|
||||
themedExports = scExports;
|
||||
}
|
||||
}
|
||||
|
||||
async function themeAugmentation() {
|
||||
interface BaseTheme {
|
||||
background: string;
|
||||
}
|
||||
interface ExtraTheme extends BaseTheme {
|
||||
accent: string;
|
||||
}
|
||||
|
||||
const base = (await import("styled-components/native")) as any as ReactNativeThemedStyledComponentsModule<
|
||||
BaseTheme
|
||||
>;
|
||||
const extra = (await import("styled-components/native")) as any as ReactNativeThemedStyledComponentsModule<
|
||||
ExtraTheme,
|
||||
BaseTheme
|
||||
>;
|
||||
|
||||
return (
|
||||
<base.ThemeProvider
|
||||
theme={{
|
||||
background: "black"
|
||||
}}
|
||||
>
|
||||
<>
|
||||
<extra.ThemeProvider
|
||||
theme={base => base} // $ExpectError
|
||||
>
|
||||
<extra.ThemeConsumer>{() => null}</extra.ThemeConsumer>
|
||||
</extra.ThemeProvider>
|
||||
<extra.ThemeProvider
|
||||
theme={base => ({
|
||||
...base,
|
||||
accent: "blue"
|
||||
})}
|
||||
>
|
||||
<extra.ThemeConsumer>{() => null}</extra.ThemeConsumer>
|
||||
</extra.ThemeProvider>
|
||||
</>
|
||||
</base.ThemeProvider>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user