Merge pull request #31017 from Kovensky/styled-components-fix-permissive-args

Fix overly permissible first argument on styled-components
This commit is contained in:
Andrew Casey
2018-12-07 10:51:02 -08:00
committed by GitHub
2 changed files with 103 additions and 26 deletions
+18 -20
View File
@@ -73,7 +73,7 @@ export type SimpleInterpolation =
| InterpolationValue
| FlattenSimpleInterpolation;
// must be an interface to be self-referential
interface FlattenSimpleInterpolation
export interface FlattenSimpleInterpolation
extends ReadonlyArray<SimpleInterpolation> {}
export type InterpolationFunction<P> = (props: P) => Interpolation<P>;
@@ -176,10 +176,9 @@ export interface ThemedStyledFunctionBase<
(
first:
| TemplateStringsArray
| NonNullable<
Interpolation<
ThemedStyledProps<StyledComponentPropsWithRef<C> & O, T>
>
| CSSObject
| InterpolationFunction<
ThemedStyledProps<StyledComponentPropsWithRef<C> & O, T>
>,
...rest: Array<
Interpolation<
@@ -187,17 +186,12 @@ export interface ThemedStyledFunctionBase<
>
>
): StyledComponent<C, T, O, A>;
// at least the first argument is required, whatever it is
<U extends object>(
first:
| TemplateStringsArray
| NonNullable<
Interpolation<
ThemedStyledProps<
StyledComponentPropsWithRef<C> & O & U,
T
>
>
| CSSObject
| InterpolationFunction<
ThemedStyledProps<StyledComponentPropsWithRef<C> & O & U, T>
>,
...rest: Array<
Interpolation<
@@ -288,19 +282,21 @@ export type StyledInterface = ThemedStyledInterface<DefaultTheme>;
export interface BaseThemedCssFunction<T extends object> {
(
first: TemplateStringsArray | NonNullable<SimpleInterpolation>,
first: TemplateStringsArray | CSSObject,
...interpolations: SimpleInterpolation[]
): FlattenSimpleInterpolation;
(
first:
| TemplateStringsArray
| NonNullable<Interpolation<ThemedStyledProps<{}, T>>>,
| CSSObject
| InterpolationFunction<ThemedStyledProps<{}, T>>,
...interpolations: Array<Interpolation<ThemedStyledProps<{}, T>>>
): FlattenInterpolation<ThemedStyledProps<{}, T>>;
<P extends object>(
first:
| TemplateStringsArray
| NonNullable<Interpolation<ThemedStyledProps<P, T>>>,
| CSSObject
| InterpolationFunction<ThemedStyledProps<P, T>>,
...interpolations: Array<Interpolation<ThemedStyledProps<P, T>>>
): FlattenInterpolation<ThemedStyledProps<P, T>>;
}
@@ -333,7 +329,8 @@ export interface ThemedStyledComponentsModule<
createGlobalStyle<P extends object = {}>(
first:
| TemplateStringsArray
| NonNullable<Interpolation<ThemedStyledProps<P, T>>>,
| CSSObject
| InterpolationFunction<ThemedStyledProps<P, T>>,
...interpolations: Array<Interpolation<ThemedStyledProps<P, T>>>
): GlobalStyleComponent<P, T>;
@@ -405,7 +402,8 @@ export function keyframes(
export function createGlobalStyle<P extends object = {}>(
first:
| TemplateStringsArray
| NonNullable<Interpolation<ThemedStyledProps<P, DefaultTheme>>>,
| CSSObject
| InterpolationFunction<ThemedStyledProps<P, DefaultTheme>>,
...interpolations: Array<Interpolation<ThemedStyledProps<P, DefaultTheme>>>
): GlobalStyleComponent<P, DefaultTheme>;
@@ -468,7 +466,7 @@ export class StyleSheetManager extends React.Component<
*/
// ONLY string literals and inline invocations of css`` are supported, anything else crashes the plugin
export type CSSProp<T = AnyIfEmpty<DefaultTheme>> =
string |
FlattenInterpolation<ThemeProps<T>>;
| string
| FlattenInterpolation<ThemeProps<T>>;
export default styled;
+85 -6
View File
@@ -14,7 +14,10 @@ import styled, {
withTheme,
ThemeConsumer,
StyledComponent,
ThemedStyledComponentsModule
ThemedStyledComponentsModule,
FlattenSimpleInterpolation,
SimpleInterpolation,
FlattenInterpolation
} from "styled-components";
import {} from "styled-components/cssprop";
@@ -101,13 +104,13 @@ const fadeIn = keyframes`
`;
const showAnimation = css`
opacity: 1;
transform: scale(1) translateY(0);
opacity: 1;
transform: scale(1) translateY(0);
`;
const hideAnimation = css`
opacity: 0;
transform: scale(0.95, 0.8) translateY(20px);
opacity: 0;
transform: scale(0.95, 0.8) translateY(20px);
`;
const entryAnimation = keyframes`
@@ -694,6 +697,8 @@ async function typedThemes() {
return props.theme.color;
}};
`;
// can't use a FlattenInterpolation as the first argument, would make broken css
// $ExpectError
const ThemedDiv4 = styled.div(themedCss);
const themedCssWithNesting = css(props => ({
@@ -714,7 +719,6 @@ async function typedThemes() {
<ThemedDiv />
<ThemedDiv2 />
<ThemedDiv3 />
<ThemedDiv4 />
<ThemeConsumer>
{theme => {
// $ExpectType string
@@ -867,3 +871,78 @@ function cssProp() {
</>
);
}
function validateArgumentsAndReturns() {
const t1: FlattenSimpleInterpolation[] = [
css({ color: "blue" }),
css`
color: blue;
`,
css`
color: ${"blue"};
`
];
const t4: FlattenInterpolation<any> = [
css`
color: ${() => "blue"};
`,
css(() => ({ color: "blue" })),
css(
() =>
css`
color: "blue";
`
)
];
// if the first argument is array-like it's always treated as a string[], this breaks things
css(
// $ExpectError
css`
${{ color: "blue" }}
`
);
// _technically_ valid as styled-components doesn't look at .raw but best not to support it
// $ExpectError
css([]);
styled.div({ color: "blue" });
styled.div(props => ({ color: props.theme.color }));
styled.div`
color: ${"blue"};
`;
// These don't work for the same reason css doesn't work
styled.div(
// $ExpectError
css`
${{ color: "blue" }}
`
);
// $ExpectError
styled.div([]);
createGlobalStyle({
":root": {
color: "blue"
}
});
createGlobalStyle`
:root {
color: blue;
}
`;
createGlobalStyle(() => ({
":root": {
color: "blue"
}
}));
// these are invalid for the same reason as in styled.div
// $ExpectError
createGlobalStyle(css`
:root {
color: ${() => "blue"};
}
`);
// $ExpectError
createGlobalStyle([]);
}