【问题标题】:RN FlatList with Typescript and Styled Components带有 Typescript 和样式化组件的 RN FlatList
【发布时间】:2021-02-04 03:56:29
【问题描述】:

SO 社区,

我无法为使用 Typescript 中的样式组件设置样式的 RN FlatList 找出正确的类型定义

所以我有这样的类型IProduct

interface IProduct {
  id: string;
  name: string;
}

然后我像这样定义FlatList 的类型

<FlatList
  data={products}
  renderItem={({ item }: { item: IProduct }) => (
    <SomeComponent item={item} />
  )}
  keyExtractor={(item: IProduct) => item.id}
/>

一切正常。 Typescript 不会抱怨,但只要我想像这样设置FlatList 的样式

const StyledFlatList = styled.FlatList`
  background-color: 'white';
`;

<StyledFlatList
  data={products}
  renderItem={({ item }: { item: IProduct }) => (
    <SomeComponent item={item} />
  )}
  keyExtractor={(item: IProduct) => item.id}
/>

我收到很多 Typescript 错误

No overload matches this call.
  Overload 2 of 2, '(props: StyledComponentPropsWithAs<typeof FlatList, DefaultTheme, {}, never>): ReactElement<StyledComponentPropsWithAs<typeof FlatList, DefaultTheme, {}, never>, string | ... 1 more ... | (new (props: any) => Component<...>)>', gave the following error.
    Type '({ item }: { item: IProduct; }) => JSX.Element' is not assignable to type 'ListRenderItem<unknown>'.
  Overload 2 of 2, '(props: StyledComponentPropsWithAs<typeof FlatList, DefaultTheme, {}, never>): 
ReactElement<StyledComponentPropsWithAs<typeof FlatList, DefaultTheme, {}, never>, string | ... 1 more ... | (new (props: any) => Component<...>)>', gave the following error.
    Type '(item: IProduct) => string' is not assignable to type '(item: unknown, index: number) => string'.ts(2769)

index.d.ts(4218, 5): The expected type comes from property 'keyExtractor' which is declared here on type 'IntrinsicAttributes & Pick<Pick<FlatListProps<unknown> & RefAttributes<FlatList<unknown>>, "ref" | "data" | "style" | "ItemSeparatorComponent" | ... 141 more ... | "key"> & Partial<...>, "ref" | ... 144 more ... | "key"> & { ...; } & { ...; } & { ...; }'

index.d.ts(4218, 5): The expected type comes from property 'keyExtractor' which is declared here on type 'IntrinsicAttributes & Pick<Pick<FlatListProps<unknown> & RefAttributes<FlatList<unknown>>, "ref" | "data" | "style" | "ItemSeparatorComponent" | ... 141 more ... | "key"> & Partial<...>, "ref" | ... 144 more ... | "key"> & { ...; } & { ...; } & { ...; }'

谁能告诉我如何解决这个错误?

【问题讨论】:

    标签: typescript react-native styled-components


    【解决方案1】:

    经过几次反复试验,我想我找到了一个可行但并不理想的解决方案。

    <StyledFlatList<any>
      data={products}
      renderItem={({ item }: { item: IProduct }) => (
        <ProductCard product={item} onProductPress={handleOnProductPress} />
      )}
      keyExtractor={(item: IProduct) => item.id}
    />
    
    

    如果你觉得还可以,请告诉我。

    更新 1:

    如果我添加建议的代码 sn-p Ben Clayton,prettier 会像这样格式化代码

    const StyledFlatList = (styled.FlatList`
      background-color: ${colors.silver};
    ` as unknown) as FlatList;
    

    我得到一个 TS 错误

    JSX element type 'StyledFlatList' does not have any construct or call signatures.
    

    更新 2:

    我尝试了&lt;React.ElementType&gt; 而不是&lt;any&gt;,而是建议here,这似乎也有效。

    <StyledFlatList<React.ElementType>
      data={products}
      renderItem={({ item }: { item: IProduct }) => (
        <ProductCard product={item} onProductPress={handleOnProductPress} />
      )}
      keyExtractor={(item: IProduct) => item.id}
    />
    

    【讨论】:

    • 我手边没有 IDE,但 TypeScript 应该已经“知道”项目的类型,因此您应该能够省略 renderItem 和 keyExtractor 参数中的所有类型信息。例如renderItem={ ({ item }) =&gt; (keyExtractor={item =&gt; .
    • 是的,我也是这么想的。不幸的是,事实并非如此。正如我之前提到的,如果我使用 RN FlatList TS 不会抱怨并推断类型,但是当我使用 styled-components 时它会抱怨,尽管我安装了 @types/styled-components
    • 啊——是的,我明白了。我记得几年前的这个,我们遇到了同样的事情。如果您定义const StyledFlatList = styled.FlatList' background-color: 'white'; ' as unknown as FlatList 会怎样。例如。让 TS 认为 StyledFlatList 只是一个“普通”的 FlatList?
    • 顺便说一句,你能详细说明一下语法吗? const StyledFlatList = styled(FlatList)' background-color: ${colors.silver}; ' as unknown as FlatList 不起作用
    • 当然很抱歉,我无法在评论中添加正确的语法...尝试将 as unknown as FlatList 放在 StyledFlatList 的声明之后。这迫使 TS 认为 StyledFlatList 是 Fl​​atList 类型。
    【解决方案2】:

    似乎将typeof 添加到另一个建议的解决方案中以更直接的方式解决了这个问题,甚至允许您从道具中排除类型:

    const StyledFlatList = (styled.FlatList`
      background-color: 'white';
    ` as unknown) as typeof FlatList;
    
    <StyledFlatList
      data={products}
      renderItem={({ item }) => (
        <SomeComponent item={item} />
      )}
      keyExtractor={(item) => item.id}
    />
    
    

    【讨论】:

      【解决方案3】:

      这个简单的解决方案对我有用:

      interface IProduct {
        id: string;
        name: string;
      }
      
      const StyledFlatList = styled(FlatList as new () => FlatList<IProduct>)`
        background-color: #f7f7f7;
      `
      

      【讨论】:

        猜你喜欢
        • 2020-11-05
        • 2020-09-10
        • 2019-08-20
        • 2020-07-12
        • 2019-11-12
        • 2019-10-27
        • 2020-06-03
        • 2022-12-16
        • 2020-11-11
        相关资源
        最近更新 更多