React Native SectionList:什么是正确的 TypeScript 类型

J. *_*ers 7 typescript react-native typescript-typings typescript-types react-native-sectionlist

我正在使用 TypeScript 构建一个 React Native 应用程序。我正在尝试使用SectionList. 我遵循了文档,这是我的代码:

  renderSectionHeader = ({ section: { title } }: { section: { title: string } }) => (
    <ListItem title={title} />
  );

  render() {
    const { sections } = this.props;
    return (
      <SafeAreaView style={styles.container}>
        <SectionList
          keyExtractor={this.keyExtractor}
          sections={[
            {title: 'Title1', data: ['item1', 'item2']},
            {title: 'Title2', data: ['item3', 'item4']},
            {title: 'Title3', data: ['item5', 'item6']},
          ]}
          renderItem={this.renderItem}
          renderSectionHeader={this.renderSectionHeader}
        />
      </SafeAreaView>
    );
  }
Run Code Online (Sandbox Code Playgroud)

但该行renderSectionHeader={this.renderSectionHeader}引发以下 TSLint 错误:

[ts]
Type '({ section: { title } }: { section: { title: string; }; }) => Element' is not assignable to type '(info: { section: SectionListData<any>; }) => ReactElement<any> | null'.
  Types of parameters '__0' and 'info' are incompatible.
    Type '{ section: SectionListData<any>; }' is not assignable to type '{ section: { title: string; }; }'.
      Types of property 'section' are incompatible.
        Type 'SectionListData<any>' is not assignable to type '{ title: string; }'.
          Property 'title' is missing in type 'SectionListData<any>'. [2322]
Run Code Online (Sandbox Code Playgroud)

SectionList破碎的种类?还是例子不对?还是我做错了什么?

aei*_*eid 7

const sections = [
  {title: 'Title1', data: ['item1', 'item2']},
  {title: 'Title2', data: ['item3', 'item4']},
  {title: 'Title3', data: ['item5', 'item6']},
];
Run Code Online (Sandbox Code Playgroud)

首先需要定义Section类型和Item类型:

type Item = string;

type Section = {
  title: string;
  data: Item[];
};
Run Code Online (Sandbox Code Playgroud)

现在您需要定义您的renderItem函数:

const renderItem: SectionListRenderItem<Item, Section> = ({item}) => {
  // return component here
};
Run Code Online (Sandbox Code Playgroud)

  • 我认为,这个答案按预期使用了泛型。同样,如果您将其用作组件,则可以使用“SectionList&lt;Item, Section&gt;”作为其返回类型来键入整个列表。 (2认同)
  • 对于其他人来说,renderItem 函数参数将这样输入:`renderItem = ({ item }:SectionListRenderItemInfo&lt; Item, Section&gt;) =&gt; {}` (2认同)

Pat*_*ski 1

我是 TypeScript 的新手,所以这个问题可能不是最好的,但你可以在这里检查 React Native 类型:React Native Types github

现在您可以在第 4243 行看到:

renderSectionHeader?: (info: { section: SectionListData<ItemT> }) => React.ReactElement<any> | null;
Run Code Online (Sandbox Code Playgroud)

这意味着 renderSectionHeader 属性需要一个带有一个参数的函数,该参数是一个具有该SectionListData<ItemT>类型的节字段的对象。

要消除您发布的错误,您可以执行以下操作:

  renderSectionHeader = ({ section: { title } }: { section: { title: string } }): React.ReactElement<any>=> (<ListItem title={title} />)

  render() {
    const { sections } = this.props;
    return (
      <SafeAreaView style={styles.container}>
        <SectionList
          keyExtractor={this.keyExtractor}
          sections={[
            {title: 'Title1', data: ['item1', 'item2']},
            {title: 'Title2', data: ['item3', 'item4']},
            {title: 'Title3', data: ['item5', 'item6']},
          ]}
          renderItem={this.renderItem}
          renderSectionHeader={({section}: {section: SectionListData<string[]>}) => this.renderSectionHeader(section)}
        />
      </SafeAreaView>
    );
  }
Run Code Online (Sandbox Code Playgroud)

希望这是正确的并且会对您有所帮助。

编辑:如果您不想在传递此 renderHeader 方法的道具期间提供类型将不会出错:

renderSectionHeader = ({ section }: {section: SectionListData<string[]>}): ReactElement<any> | null => (<Text>{section.title}</Text>)
Run Code Online (Sandbox Code Playgroud)