描述
我正在try 创建一个自定义的ManagedList
组件,其中将有props
,其中类型为FlatListProps<itemT>
或SectionListProps<itemT, SectionT = DefaultSectionT>
,附加{ listType: ListType; dismissKeyboardOnPress?: boolean; dismissElevatedUIElements?: boolean;
属性.
执行
为此,我创建了一个自定义类型ListType
和ListProps
:
type ListType = 'flat' | 'section';
type ListProps<listT extends ListType, itemT> = (
listT extends 'flat'
? FlatListProps<itemT>
: SectionListProps<itemT>
) & {
listType: ListType;
dismissKeyboardOnPress?: boolean;
dismissElevatedUIElements?: boolean;
};
然后我创建了一个函数组件,它接受泛型参数listT extends ListType
,如下所示:
function ManagedList<listT extends ListType>(
props: Readonly<ListProps<listT, any>>
) {
const {
listType,
dismissKeyboardOnPress,
dismissElevatedUIElements,
data,
sections, // destructing sections throws error #1
renderItem,
...otherProps
} = props;
...
let listCmp;
if (listType === 'flat') {
listCmp = (
<FlatList
data={data}
renderItem={renderItem} // defining renderItem prop throws error #2
onTouchStart={touchStartHandler}
onLayout={layoutHandler}
onContentSizeChange={contentSizeChangeHandler}
onScroll={scrollHandler}
showsVerticalScrollIndicator={false}
{...otherProps}
/>
);
} else {
listCmp = (
<SectionList
sections={sections}
renderItem={renderItem} // defining renderItem prop throws error #2
onTouchStart={touchStartHandler}
onLayout={layoutHandler}
onContentSizeChange={contentSizeChangeHandler}
onScroll={scrollHandler}
showsVerticalScrollIndicator={false}
{...otherProps}
/>
);
}
return (
<View style={styles.listContainer}>
{listCmp}
{contentHeight > containerHeight && (
<Fragment>
<View style={styles.scrollbarTrack} />
<Animated.View
style={[styles.scrollbarThumb, animatedSyles]}
/>
</Fragment>
)}
</View>
);
错误
错误#1
正如代码中提到的,从props
析构sections
会引发以下错误:
Property 'sections' does not exist on type 'Readonly<ListProps<listT, any>>'.ts(2339)
错误#2
定义renderItem
个props 时会抛出第二个错误.我相信这是因为FlatList
和SectionList
有不同的renderItem
个定义/类型.FlatList
有以下类型的renderItem
prop:
renderItem({
item: ItemT,
index: number,
separators: {
highlight: () => void;
unhighlight: () => void;
updateProps: (select: 'leading' | 'trailing', newProps: any) => void;
}
}): JSX.Element;
SectionList
的renderItem
props 类型:
renderItem({
item: ItemT,
index: number,
section: object, // <--- This is different
separators: {
highlight: () => void;
unhighlight: () => void;
updateProps: (select: 'leading' | 'trailing', newProps: any) => void;
}
}): JSX.Element;
我试过什么?
为了解决错误#1,我try 使用Type Guards:
const {
listType,
dismissKeyboardOnPress,
dismissElevatedUIElements,
data,
renderItem,
...otherProps
} = props;
let sections;
if(props.sections) {
sections = props.section;
}
// or
const sections = props?.section ?? undefined;
但是所有这些类型警卫try 都显示了类似的错误,因为sections
不存在于props
对象中.
我不知道怎么解决错误#2个问题.
NOTE:我试图实现的是有一个单独的自定义组件来使用FlatList
或SectionList
,这些组件分配了一些事件处理程序.任何其他更好的方法来实现这个功能都是一个很好的答案.