From f41f226705a10ccefded00f4dae4f7389e3e0344 Mon Sep 17 00:00:00 2001 From: Anton Evzhakov Date: Sat, 11 Jul 2020 14:56:08 +0300 Subject: [PATCH] fix: typings for additional props (#622) --- src/StyledMeta.ts | 6 +++ src/babel/evaluators/templateProcessor.ts | 2 +- src/babel/types.ts | 2 +- src/core/css.ts | 4 +- src/react/styled.ts | 25 ++++++------ types/styled.ts | 48 +++++++++++++++++------ 6 files changed, 57 insertions(+), 30 deletions(-) create mode 100644 src/StyledMeta.ts diff --git a/src/StyledMeta.ts b/src/StyledMeta.ts new file mode 100644 index 000000000..e3aa691a4 --- /dev/null +++ b/src/StyledMeta.ts @@ -0,0 +1,6 @@ +export type StyledMeta = { + __linaria: { + className: string; + extends: StyledMeta; + }; +}; diff --git a/src/babel/evaluators/templateProcessor.ts b/src/babel/evaluators/templateProcessor.ts index 851a2e588..5fd0efa94 100644 --- a/src/babel/evaluators/templateProcessor.ts +++ b/src/babel/evaluators/templateProcessor.ts @@ -10,7 +10,7 @@ import generator from '@babel/generator'; import { units } from '../units'; import { State, StrictOptions, TemplateExpression, ValueCache } from '../types'; -import { StyledMeta } from '../../react/styled'; +import { StyledMeta } from '../../StyledMeta'; import isSerializable from '../utils/isSerializable'; import { debug } from '../utils/logger'; diff --git a/src/babel/types.ts b/src/babel/types.ts index 4c8c7b424..1d6d29fb1 100644 --- a/src/babel/types.ts +++ b/src/babel/types.ts @@ -1,6 +1,6 @@ import { types as t, TransformOptions } from '@babel/core'; import { NodePath } from '@babel/traverse'; -import { StyledMeta } from '../react/styled'; +import { StyledMeta } from '../StyledMeta'; export type JSONValue = string | number | boolean | JSONObject | JSONArray; diff --git a/src/core/css.ts b/src/core/css.ts index 5c1bba067..0b0d5380d 100644 --- a/src/core/css.ts +++ b/src/core/css.ts @@ -1,4 +1,4 @@ -type CSSMeta = string; +import { StyledMeta } from '../StyledMeta'; type CSSProperties = { [key: string]: string | number | CSSProperties; @@ -6,7 +6,7 @@ type CSSProperties = { export default function css( _strings: TemplateStringsArray, - ..._exprs: Array + ..._exprs: Array ): string { throw new Error( 'Using the "css" tag in runtime is not supported. Make sure you have set up the Babel plugin correctly.' diff --git a/src/react/styled.ts b/src/react/styled.ts index 13ec1cca4..4799e98d0 100644 --- a/src/react/styled.ts +++ b/src/react/styled.ts @@ -7,13 +7,7 @@ import * as React from 'react'; // eslint-disable-line import/no-extraneous-dependencies import validAttr from '@emotion/is-prop-valid'; import { cx } from '../index'; - -export type StyledMeta = { - __linaria: { - className: string; - extends: StyledMeta; - }; -}; +import { StyledMeta } from '../StyledMeta'; type Options = { name: string; @@ -170,16 +164,21 @@ type HtmlStyledTag = < ) => StyledComponent; type ComponentStyledTag = < - Props = T extends React.FunctionComponent ? TProps : T + OwnProps = {}, + TrgProps = T extends React.FunctionComponent ? TProps : T >( strings: TemplateStringsArray, // Expressions can contain functions only if wrapped component has style property - ...exprs: Props extends { style?: React.CSSProperties } - ? Array string | number)> + ...exprs: TrgProps extends { style?: React.CSSProperties } + ? Array< + StaticPlaceholder | ((props: OwnProps & TrgProps) => string | number) + > : StaticPlaceholder[] -) => T extends React.FunctionComponent - ? StyledMeta & T - : StyledComponent; +) => keyof OwnProps extends never + ? T extends React.FunctionComponent + ? StyledMeta & T + : StyledComponent + : StyledComponent; type StyledJSXIntrinsics = { readonly [P in keyof JSX.IntrinsicElements]: HtmlStyledTag

; diff --git a/types/styled.ts b/types/styled.ts index c9b03930a..39c412881 100644 --- a/types/styled.ts +++ b/types/styled.ts @@ -84,16 +84,38 @@ styled.a` } `({ href: 'about:blank' }); -// Issue #536 -const Title = styled.div<{ background: string }>` - background: ${props => props.background}; -`; - -// $ExpectType "extends" -isExtends>(); - -css` - ${Title} { - color: green; - } -`; +((/* Issue #536 */) => { + const Title = styled.div<{ background: string }>` + background: ${props => props.background}; + `; + + // $ExpectType "extends" + isExtends>(); + + css` + ${Title} { + color: green; + } + `; +})(); + +((/* Issue #622 */) => { + const Wrapper = styled.div<{ prop1: boolean }>` + width: 1em; + background-color: ${props => (props.prop1 ? 'transparent' : 'green')}; + `; + + const styledTag = styled(Wrapper); + + const NewWrapper = styledTag<{ prop2: string }>` + width: 2em; + background-color: ${props => (props.prop1 ? 'transparent' : 'red')}; + color: ${props => props.prop2}; + `; + + // $ExpectType Validator | undefined + NewWrapper.propTypes!.prop1; + + // $ExpectType Validator | undefined + NewWrapper.propTypes!.prop2; +})();