React Native + TypeScript 联合类型渲染列表项的类型报错问题咨询
React Native + TypeScript 联合类型渲染列表项的类型报错问题咨询
嘿,我瞅了你这段代码,立马就发现问题出在哪了——TypeScript对联合类型的类型检查比较严格,咱们直接看核心问题:
你定义了video和image两个类型,然后把列表项的类型设成了它们的联合类型video | image。但在RenderItem里直接访问item.duration的时候,TypeScript没办法确定当前的item到底是video还是image,毕竟image类型里根本没有duration这个属性,所以肯定会给你抛类型报错。
给你几个实用的解决办法,你可以根据自己的场景选:
方法1:用in操作符做类型缩小
这是最常用的方式,通过判断属性是否存在来让TypeScript自动缩小类型范围:
import { FlatList } from "react-native" import { View, Text } from 'react-native' import React from 'react' type video = { name: string, duration: number, } type image = { name: string, width: number, height: number, } const RenderItem = ({ item }: { item: video | image }) => { return ( <View> {'duration' in item && <Text>{item.duration}</Text>} </View> ) } const mediaContent = [] // 这里可以补全你的媒体数据
当'duration' in item这个条件成立时,TypeScript就会知道当前的item一定是video类型,自然就能安全访问duration了。
方法2:使用类型断言(谨慎使用)
如果你能确定某些场景下item肯定是video类型,可以用类型断言强制告诉TypeScript:
const RenderItem = ({ item }: { item: video | image }) => { return ( <View> {(item as video).duration && <Text>{(item as video).duration}</Text>} </View> ) }
不过这种方式要注意,如果item实际是image类型,(item as video).duration会返回undefined,虽然不会报错,但可能影响页面渲染逻辑,所以只在你能确保类型的场景下用。
方法3:自定义类型守卫函数
如果你的判断逻辑比较复杂,可以写一个专门的类型守卫函数,明确告诉TypeScript某个值属于哪个类型:
import { FlatList } from "react-native" import { View, Text } from 'react-native' import React from 'react' type video = { name: string, duration: number, } type image = { name: string, width: number, height: number, } // 自定义类型守卫函数 function isVideo(item: video | image): item is video { return (item as video).duration !== undefined; } const RenderItem = ({ item }: { item: video | image }) => { return ( <View> {isVideo(item) && <Text>{item.duration}</Text>} </View> ) } const mediaContent = []
这个函数返回true的时候,TypeScript就会认定item是video类型,后续访问duration就完全没问题啦。
内容来源于stack exchange
相关产品推荐
相关产品推荐

