Skip to content
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 #734

Merged
merged 11 commits into from
Aug 27, 2020
Merged

Typescript #734

merged 11 commits into from
Aug 27, 2020

Conversation

Titozzz
Copy link

@Titozzz Titozzz commented Aug 1, 2020

2 'bugs' might have been fixed btw

Platforms affected

What does this PR do?

What testing has been done on this change?

Tested features checklist

2 'bugs' might have been fixed btw
@Titozzz Titozzz changed the title 🚧 wip(Carousel): huge revamp of carousel's logic, props and behavior WIP: Typescript Aug 1, 2020
@bd-arc
Copy link
Contributor

bd-arc commented Aug 2, 2020

@Titozzz This is looking great, kudos to you 👍

The only issue is that some of the code styling rules you've used are absolute no-go's for us — the rules we use are opinionated and enforced company-wide.

Particularly:

  1. 4 spaces for indentation.
  2. Space required before methods' parenthesis.
  3. Ternaries are written this way:
let nextActiveItem =
    typeof this._activeItem !== 'undefined' ?
        this._activeItem :
        nextFirstItem;

Apart from that, excellent job so far!

Can you tell me why you've removed the eslint file?

@Titozzz
Copy link
Author

Titozzz commented Aug 2, 2020

I just aligned the repo to the default config from eslint community. No problem, I'll update it back

@Titozzz
Copy link
Author

Titozzz commented Aug 5, 2020

I tried reverting to your config + adding some typescript defaults. Lemme know if that need any more changes

@Titozzz
Copy link
Author

Titozzz commented Aug 5, 2020

I've made sure the example works, let me know if I need to test more

@Titozzz Titozzz marked this pull request as ready for review August 5, 2020 23:49
@Titozzz Titozzz changed the title WIP: Typescript Typescript Aug 5, 2020
@bd-arc
Copy link
Contributor

bd-arc commented Aug 6, 2020

@Titozzz Amazing work, thank you so much 🙏

I'll set aside some time this weekend to review it in length. Anything particular I should know about using https://github.com/react-native-community/bob?

@Titozzz
Copy link
Author

Titozzz commented Aug 8, 2020

Nope it's just used in the prepare phase to build the code

@bd-arc bd-arc mentioned this pull request Aug 10, 2020
offset: number;
width: number;
height: number;
status: 1 | 2 | 3 | 4;
Copy link

@narender2031 narender2031 Aug 13, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can also define the types of these numbers. It will be easy to understand when someone is trying to use it.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried being as precise as I could and 1|2|3|4 is usable by a function expecting number but it's also more clear

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm ok with keeping the numbers as is. However we should probably copy the following comment there as well for clarity's sake:

// 1 -> loading | 2 -> loaded | 3 -> transition finished | 4 -> error

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bd-arc & @Titozzz we can do one more thing. We can add the meaning of the numbers in the documentation. So that users can understand the meaning of these numbers.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can probably replace with an enum. That'll make things easier

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Titozzz Great idea!

activeDotIndex: number;
dotsLength: number;
activeOpacity?: number;
carouselRef?: Carousel<unknown> | null;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

carouselRef?: Carousel<any> | null; I think we can replace unknown with any. Please share your thoughts regarding this.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried avoiding all "any's". I suppose I could also template this so that it would be TData if you prefer

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Titozzz Let's go with TData if you don't mind :-)

@narender2031
Copy link

@Titozzz @bd-arc TypeScript looks fine to me. add a few suggestions. Please take look and share your thoughts.

import type Carousel from 'src/carousel/Carousel';

type ParallaxImageProps = {
carouselRef: Carousel<unknown> | null; // passed from <Carousel />

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I mention above, If we can replace Unknown with any. Then please change here also.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same answer as Pagination

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, let's use TData here as well.

@bd-arc
Copy link
Contributor

bd-arc commented Aug 13, 2020

@Titozzz Just went over the whole PR and, as far as I can tell, you've done an astounding job! Thank you so much 🙏

Let me know once you're done with the really minor corrections and then... Let's get this merged!

PS — Thanks a lot @narender2031 for your thorough review 🙂

@nelsonprsousa
Copy link

nelsonprsousa commented Aug 15, 2020

Hey guys,

I would like to test this. Currently I have "react-native-snap-carousel": "4.0.0-beta.5" on my package.json. What should I do to test this PR?

Maybe with the last commit hash? 🤔

Thank you

@bd-arc
Copy link
Contributor

bd-arc commented Aug 15, 2020

@nelsonprsousa You can target any commit of the repo with its SHA.

Here's an example with this PR's current latest commit:

"react-native-snap-carousel": "https://github.com/archriss/react-native-snap-carousel#e719467"

@nelsonprsousa
Copy link

I tried it, but got this error:
Screenshot 2020-08-15 at 12 57 45

I am sure I am missing something here 🤔

@Titozzz
Copy link
Author

Titozzz commented Aug 15, 2020

I tried it, but got this error:
Screenshot 2020-08-15 at 12 57 45

I am sure I am missing something here 🤔

Please try cloning it from my fork

@nelsonprsousa
Copy link

Please try cloning it from my fork

Seems to work with your fork. However, once I yarn I get this error:
Screenshot 2020-08-15 at 18 29 40

Here's my package.json: https://gist.github.com/nelsonprsousa/61ef81bdddc0823bb9ec793924d4c22b

Do you know if this is a local related problem?

@Titozzz
Copy link
Author

Titozzz commented Aug 18, 2020

@nelsonprsousa Fixed it, thanks :)

I uploaded a packed version if you want to try it out just download and you can add it with yarn add "path"
https://github.com/Titozzz/files/blob/master/react-native-snap-carousel-v4.0.0-beta.5.tgz

@bd-arc @narender2031 fixes are done, can't do many tests as I don't have a good connection here, but should be just fine.
Please test 🚀

@nelsonprsousa
Copy link

@nelsonprsousa Fixed it, thanks :)

I uploaded a packed version if you want to try it out just download and you can add it with yarn add "path"
https://github.com/Titozzz/files/blob/master/react-native-snap-carousel-v4.0.0-beta.5.tgz

@bd-arc @narender2031 fixes are done, can't do many tests as I don't have a good connection here, but should be just fine.
Please test 🚀

Now I could add it 👍
Already tested our application with this version and it is working as expected. 🚀 We are using the Carousel and Pagination, too.

I was also expecting to have types with the migration to TypeScript. Am I missing something here? Maybe we need to do something else?

Screenshot 2020-08-18 at 14 19 35

Nevertheless the runtime app looks 👌

@Titozzz
Copy link
Author

Titozzz commented Aug 18, 2020

Thanks for testing, I fcked up the path to the d.ts file 🙄 , now it is fixed @nelsonprsousa

Feel free to edit the package.json if you don't wanna reinstall 😛

@nelsonprsousa
Copy link

nelsonprsousa commented Aug 18, 2020

Thanks for testing, I fcked up the path to the d.ts file 🙄 , now it is fixed @nelsonprsousa

Feel free to edit the package.json if you don't wanna reinstall 😛

Types are now working 👌 Awesome job! 🚀

Just find it hard to compile it without any error 😅

This is my code:

const renderItem = (baseData: {
    index: number;
    dataIndex: number;
    item: IPointOfSale;
}): ReactNode => (
    <Card
        title={baseData.item.title}
        subtitle={baseData.item.subtitle}
        imagePath={baseData.item.imagePath}
        width={96}
        height={25}
        onPress={navigate(navigation, baseData.item.navigation)}
    />
);

<Carousel
    ref={carouselRef}
    data={pointsOfSale}
    renderItem={renderItem}
    onScrollIndexChanged={setActiveSlide}
    sliderWidth={theme.mixins.width}
    itemWidth={theme.mixins.width}
    hasParallaxImages
    containerCustomStyle={{
        overflow: 'visible',
        marginLeft: theme.mixins.widthPercentageToDP(2),
    }}
    inactiveSlideScale={0.65}
    inactiveSlideOpacity={0.35}
/>

But I am getting this:
Type '(baseData: { index: number; dataIndex: number; item: IPointOfSale;}) => ReactNode' is not assignable to type '(baseData: { index: number; dataIndex: number; item: unknown; }, parallaxData?: { scrollPosition: Value | undefined; carouselRef: ScrollView | FlatList<unknown> | null; vertical?: boolean | undefined; sliderWidth?: number | undefined; sliderHeight?: number | undefined; itemWidth?: number | undefined; itemHeight?: nu...'. Types of parameters 'baseData' and 'baseData' are incompatible. Type '{ index: number; dataIndex: number; item: unknown; }' is not assignable to type '{ index: number; dataIndex: number; item: IPointOfSale; }'. Types of property 'item' are incompatible. Type 'unknown' is not assignable to type 'IPointOfSale'.ts(2322)

Maybe the problem is the item's type? 🤔

@Titozzz
Copy link
Author

Titozzz commented Aug 20, 2020

I'll do some tests and come back at you

@nelsonprsousa
Copy link

nelsonprsousa commented Aug 21, 2020

Hey guys, quick update on my side after testing:
All working now 🚀

Thanks @Titozzz for your time and patience with this awesome PR! You rock 🚀

@bd-arc can we merge this to v4 branch to test as v4.0.0-beta.6?

@Titozzz
Copy link
Author

Titozzz commented Aug 21, 2020

I need to push a few fixes to parallax image,but then yeah we should merge

@bd-arc
Copy link
Contributor

bd-arc commented Aug 22, 2020

@Titozzz Can't thank you enough for your amazing work on this one 👍

@nelsonprsousa That's exactly the plan! As soon as @Titozzz tells me it's ready, I'll publish a new release :-)

@Titozzz
Copy link
Author

Titozzz commented Aug 24, 2020

I've had to make a few key changes to make sure types would be as close to reality as they needed to be.
Most library don't bother doing this but it will make the user experience better.
We could have typed the carousel like that:

{
  vertical?: boolean,
  height?: number,
  width?: number,
}

That's the easy way.
Instead I've gone

{
  vertical: false,
  width: number
} | {
  vertical: true,
  height: number,
}

Which is more accurate, and doesn't allow for user error.
The drawback is now that when using TypeScript you need to specify vertical={false} (or true) explicitly.
I've tried for a long time to make it default to horizontal so that user would have the horizontal types when not specifying but that is just not possible with the current TS version.
Note that this doesn't impact the JS users, and is not a breaking change for them. Only TS users will see a difference.
I've also removed the hasParallaxImages prop, and I'm now always passing a second argument, this has no perf impact, and vastly simplified the types. Now the function renderItem is properly typed depending on vertical.

There are plenty of things I'd like to go over but this PR has waited enough and code is working fine as is.

Unless anyone comments otherwise, has bugs, this is READY TO MERGE @bd-arc

@bd-arc
Copy link
Contributor

bd-arc commented Aug 26, 2020

This is superb! I'll do a few more tests and will most certainly merge and publish your PR tomorrow.

Thank you for your awesome job on this one @Titozzz 👍

@Titozzz
Copy link
Author

Titozzz commented Aug 26, 2020

Can't wait to get some feedbacks on this. I'm playing with reanimated 2 right now

@bd-arc bd-arc merged commit 089ecd3 into meliorence:4.0.0-beta.x Aug 27, 2020
@bd-arc
Copy link
Contributor

bd-arc commented Aug 27, 2020

@Titozzz Merged and published!

Two observations:

  1. The code styling you've used is pretty far from what we enforce in the company and what is defined in the .eslintrc file (I've just updated it by the way). For some reason, I can no longer get ESLint to work and autofix as much of it as possible. Better luck on your end?
  2. Nice to hear about Reanimated 2. The plugin could really use an addition like this one further down the road ;-)

@Titozzz
Copy link
Author

Titozzz commented Aug 27, 2020

@bd-arc Any way we can chat, other that using github issues ? :)

@Titozzz
Copy link
Author

Titozzz commented Aug 27, 2020

#750 for 1)

@Aryk
Copy link

Aryk commented Sep 29, 2020

I noticed that the Carousel component is missing some props from "InheritedPropsFromFlatlist", namely extraData which I required on my component when the size changes (lets say a photo finishes uploading).

Should I make a separate ticket for that?

@Aryk
Copy link

Aryk commented Apr 5, 2021

@Titozzz

I was looking at this again. Few things:

  1. Why are we using a "type" for CarouselProps instead of "interface"? I can't extend from CarouselProps to create other interfaces because it is not a static type. I believe in the @types version it was an interface.
  2. Why are optional props listed as "required". My guess is that that type is used internally in the library but most of those values are defaulted by the library. To the user, they should all be optional.
  3. renderItem requires "parallaxData" as the second argument but I don't believe it's required by the library to work.
  4. Switch vertical=true and vertical=false doesn't get me valid type checking for the other attributes like sliderWidth. I'll see vertical={false} and it will still blow up saying it couldn't find sliderWidth in the types. I believe you used interfaces I believe this would work properly.

Is there another way I should be looking at getting typescript support for 4.0.0-beta?

@bd-arc
Copy link
Contributor

bd-arc commented Apr 5, 2021

@Aryk Thanks for the feedback! @Titozzz did an amazing job migrating everything to TypeScript, but we know that a few things probably need some fine-tuning.

You're more than welcome to update the Typescript definition and submit a PR if you feel like it. Just make sure to ping me when you do so or I'm probably going to miss it.

@Titozzz
Copy link
Author

Titozzz commented Apr 5, 2021

There is definitely a big need for polishing. I'll try fixing this in the next weeks

itenl pushed a commit to itenl/react-native-snap-carousel that referenced this pull request Aug 27, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants