emotion-js / emotion

👩‍🎤 CSS-in-JS library designed for high performance style composition
https://emotion.sh/
MIT License
17.41k stars 1.11k forks source link

Styling FlatList changes its type #2888

Open bam-charlesbo opened 2 years ago

bam-charlesbo commented 2 years ago

Introduction

Hi everyone, Thanks for your work on this great library, I really enjoy using it. Especially installing it :) I'm concerned about a bad behaviour with TypeScript. Styling a FlatList is modifying its type and then returns type error with actual code. I found a fix a really dislike.

Git repository to clone

To allow you to repro this bug : Here is the link to a public repo

Bug description

This code returns no error

const renderNote: ListRenderItem<Note> = ({item}) => {
  return (
      <Text>{item.text}</Text>
  );
};

export const Notes = ({notes}: NotesProps) => {
  return (
    <FlatList
      data={notes}
      keyExtractor={item => item.id}
      renderItem={renderNote}
    />
  );
};

This code does

Fix description

I found this fix, that I really dislike :

const NotesStyle = styled.FlatList({
  width: '100%',
}) as unknown as typeof FlatList;

Environment information

Andarist commented 2 years ago

Please always try to share a repro case in a runnable form - either by providing a git repository to clone or a codesandbox. OSS maintainers usually can't afford the time to set up the repro, even if exact steps are given.

bam-charlesbo commented 2 years ago

Please always try to share a repro case in a runnable form - either by providing a git repository to clone or a codesandbox. OSS maintainers usually can't afford the time to set up the repro, even if exact steps are given.

I just edited my issue, and added a public repo. Hope it suits you this way.

Thanks for your time.

Andarist commented 2 years ago

It's a limitation of TypeScript. We can't "capture" and retain the generic nature of FlatList when we wrap it.

As a workaround you can use this patch:

diff --git a/components/Notes.tsx b/components/Notes.tsx
index 38e5661..418a358 100644
--- a/components/Notes.tsx
+++ b/components/Notes.tsx
@@ -24,9 +24,9 @@ export const Notes = ({notes}: NotesProps) => {
   );
 };

-const NotesStyle = styled.FlatList({
+const NotesStyle = styled(FlatList<Note>)({
   width: '100%',
-}) as unknown as typeof FlatList;
+});

 const NoteItemText = styled.Text({
   fontSize: 25,
skudirka-tw commented 1 year ago

This also applies to the SectionList component.

skudirka-tw commented 1 year ago

It's a limitation of TypeScript. We can't "capture" and retain the generic nature of FlatList when we wrap it.

As a workaround you can use this patch:

diff --git a/components/Notes.tsx b/components/Notes.tsx
index 38e5661..418a358 100644
--- a/components/Notes.tsx
+++ b/components/Notes.tsx
@@ -24,9 +24,9 @@ export const Notes = ({notes}: NotesProps) => {
   );
 };

-const NotesStyle = styled.FlatList({
+const NotesStyle = styled(FlatList<Note>)({
   width: '100%',
-}) as unknown as typeof FlatList;
+});

 const NoteItemText = styled.Text({
   fontSize: 25,

@Andarist I tried your solution. It looked fine in the IDE, no errors and type looks to be carried onto the component props. However, when I compile I get the following error:

unknown node of type "TSInstantiationExpression" with constructor "Object"