-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Typescript issue with passed props on extended components #672
Comments
Hello @epeli, as far as I know emotion styled interface require two parameters, because it supports also tagged template strings. Until recently it was impossible to infer types passed to tagged templates via generics (TS: Support passing generics to tagged template string #11947 - PR got merged to roll out in typescript 2.9, let's see how it'll go). It's mentioned in Emotion docs. About your example: type StyledProps = React.HTMLAttributes<HTMLDivElement> /* Because it's a div and acepts html props*/
& ViewProps /* Any additional props you may want to pass to View (here's void)*/
& InjectedProps /* Your injected props (here's red?) */
// Component<StyledProps> is not `div` anymore. It's StyledComponent type - in your case with additional injected props
// which you can just declare as React.ComponentType<StyledProps>
const MaybeRed = styled<StyledProps, React.ComponentType<StyledProps>>(View)(props => ({
backgroundColor: props.red ? "red" : "white"
})); Here's CodeSandbox It's a bit verbose, but if you reuse View component all the time - just declare Also there is currently an open PR to improve Emotion typings, so it's gonna get only better :) Btw. I kind of new to TypeScript, so please correct me if I'm spreading nosense🙃 |
@epeli Hi, I'm from glamorous. type Fun<First, Second> = (a: First, ar: Second) => boolean;
interface ExampleBase<First> {
<Second>(x: First): Fun<First, Second>;
}
interface Example extends ExampleBase<'div'>, ExampleBase<'a'> {}
declare const ex: Example;
ex<{ x: number }>('div'); // First is infered to 'div'
ex<{ x: number }>('a'); // First is infered to 'a' However, current emotion type does not use this 'two levels of generic', so it's impossible to infer second type parameter when you give the first parameter to emotion('div')<{ red: boolean }>((props) => ({
backgroundColor: props.red ? 'red' : 'white',
}); If you think this looks awful and glamorous approach is better, I'm willing to change type structure. |
I wonder if it would be possible to do completely different typings when it is used as tagged template and when used as function call with an object param? Ie. it would work like glamorous when the object is passed. Should be possible at least with conditional types or maybe even just with function overrides?
If works when extending existing component created by emotion personally I'm cool with it as it's pretty irrelevant syntastical difference, but glamorous style would make it easier to migrate from it. I think there are quite a people few coming from glamorous now as it is unmaintained. Is there a way I could test those types? |
|
You mention "My improved type does not include first parameter" so just assumed that you have made a pr or something improve ts typings in emotion. |
Woo, this is fixed by #678. Thanks! |
Hey, ran into the same problem. Is this release being published soon? |
@yahyavi It's already been published. You probably need to update to |
@mitchellhamilton Thanks. I tried 9.2.1, but it does not compile for me. I thought this is resolved in 9.2.2 that is tagged as released but not pushed to npmjs? The last version that works for me is 9.1.3. |
@yahyavi Could you check the document? In emotion@9.2.1, we changed typings so it requires different type parameters. |
Hi! since glamorous is being deprecated I'm trying to migrate to emotion but I'm stuck with Typescript types.
emotion
version: 9.1.3react
version: 16.3.2typescript
version: 2.8.3My app is built using glamorous by extending every component from a custom
View
component (inspired by React Native).This works great but often I do use props passing and type them too. This is no trouble for glamorous typescript typings but react-emotion seem to trip on it:
The full type error is here:
And the error on
props
is justParameter 'props' implicitly has an 'any' type.
.Also glamorous does not require the second
"div"
type parameter, wonder why emotion does?The text was updated successfully, but these errors were encountered: