【发布时间】:2020-11-14 16:44:30
【问题描述】:
TypeScript 真的很棒,只是目前我觉得我为 TypeScript 工作比为我工作更多。
我有一个在轮播中呈现餐厅结果的 FlatList。
const renderRestaurantRows = ({ item }) => (
<Carousel
id={item.id}
name={item.name}
/>
);
const renderBottomSheetRestaurantList = () => (
<View style={[styles.listView, { height: topSnapPoint }]}>
<FlatList
data={restaurants}
keyExtractor={(item) => `row-${item.id}`}
renderItem={renderRestaurantRows}
/>
</View>
);
TypeScript 抱怨 item 和 Binding element 'item' implicitly has an 'any' type - 是有道理的。所以我试着告诉它会发生什么:
interface RestaurantItem {
item: {
id: string;
name: string;
};
}
const renderRestaurantRows = ({ item }: RestaurantItem) => (
<Carousel
id={item.id}
name={item.name}
/>
);
但随后 TS 抱怨 data={restaurants] 和 Type 'Restaurant[]' is not assignable to type 'readonly { id: string; name: string; imageUrl: string; rating: number; reviews: number; } 以及大量其他信息。
是否有人可以分享解决方案并解释将来如何为其他类似案例找到这样的解决方案?
更新
restaurants 是从自定义挂钩中获取的。它被定义为一个 Restaurant 对象数组:
interface Restaurant {
id: string;
name: string;
}
export default function useRestaurantSearch() {
const [restaurants, setRestaurants] = useState<Restaurant[] | null>(null);
...
更新 2
各位大大感谢cmets,根据两个建议,我重写了代码:
import useRestaurantSearch from '../hooks/useRestaurantSearch';
export default function RestaurantPage() {
const renderRestaurantRows = ({ item }: Restaurant) => (
<Carousel
id={item.id}
name={item.name}
/>
);
const renderBottomSheetRestaurantList = () => (
<View style={[styles.listView, { height: topSnapPoint }]}>
<FlatList
data={restaurants}
keyExtractor={(item) => `row-${item.id}`}
renderItem={renderRestaurantRows}
/>
</View>
);
这一次,{ item }: Restaurant 和 Cannot find name 'Restaurant' 出现错误。这并不奇怪,因为 Restaurant 是在外部挂钩文件 ../hooks/useRestaurantSearch 中定义的。我需要以某种方式导入它吗?
更新 3
玩了几个小时后,我到了这一点:
const renderRestaurantRows = (result: { item: Restaurant }) => {
return <Carousel {...result.item} />;
};
const renderBottomSheetRestaurantList = () => (
<View style={[styles.listView, { height: topSnapPoint }]}>
<FlatList
data={restaurants}
keyExtractor={(item) => `row-${item.id}`}
renderItem={renderRestaurantRows}
/>
</View>
);
renderItem 生成一个对象,该对象包含item 键下的每个餐厅数据。例如,其中一个对象可能是:
{
"index": 18,
"item": Object {
"coordinates": Object {
"latitude": 123,
"longitude": -123,
},
"id": "dfg987fshjsdfh",
"name": "Yummy Food",
},
"separators": Object {
"highlight": [Function highlight],
"unhighlight": [Function unhighlight],
"updateProps": [Function updateProps],
},
}
当我传递result 对象时,我可以让TS 知道对象内部的item 并将其转换为Restaurant 类型。我用 (result: { item: Restaurant }). However, when I try to directly destructure the resultobject with({ item }: Restaurant)it gives me the errorProperty 'item' does not exist on type 'Restaurant'`来做到这一点。知道为什么吗?
【问题讨论】:
-
你是如何定义
restaurants的类型的?尝试用 RestaurantItem[] 注释这个数组 -
@Drag13 请查看我更新的问题。
-
您正在获取 Restaurant 类型,但想要处理 RestaurantItem 类型。它们不兼容,TypeScript 对此抱怨。您应该使用相同类型或餐厅类型的子集
-
我会说你找到了解决方案,只需导入类型就可以了)
-
@ben 我相信如果你要解构你需要这样做:
{ item }: { item: Restaurant }
标签: reactjs typescript