reactjs - expo-assets useAssets: Typ 'Asset' kan inte tilldelas typen 'ImageSourcePropType'
Följande det lilla exemplet som ges av expo-asset:s dokumentation, ger det att skicka ett element från asset-arrayen till en Image source-egenskap följande TypeScript-fel:
No overload matches this call.
Overload 1 of 2, '(props: ImageProps | Readonly<ImageProps>): Image', gave the following error.
Type 'Asset' is not assignable to type 'ImageSourcePropType'.
Type 'Asset' is not assignable to type 'ImageURISource'.
Types of property 'width' are incompatible.
Type 'number | null' is not assignable to type 'number | undefined'.
Type 'null' is not assignable to type 'number | undefined'.
Overload 2 of 2, '(props: ImageProps, context: any): Image', gave the following error.
Type 'Asset' is not assignable to type 'ImageSourcePropType'.ts(2769)
index.d.ts(3783, 5): The expected type comes from property 'source' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes<Image> & Readonly<ImageProps>'
index.d.ts(3783, 5): The expected type comes from property 'source' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes<Image> & Readonly<ImageProps>'
Jag använder macOS med Node version 16.15.0, Yarn version 1.22.18 och expo-cli version 5.4.7.
Problemet kan reproducera genom:
- initierar ett nytt projekt med
expo initoch väljerblank (Typescript)-mallen - lägger till expo-asset med
expo install expo-asset
Filen package.json ser ungefär ut så här (skript borttagna för lättare läsning):
{
"name": "asset-test",
"version": "1.0.0",
"main": "node_modules/expo/AppEntry.js",
"dependencies": {
"expo": "~45.0.0",
"expo-asset": "~8.5.0",
"expo-status-bar": "~1.3.0",
"react": "17.0.2",
"react-dom": "17.0.2",
"react-native": "0.68.2",
"react-native-web": "0.17.7"
},
"devDependencies": {
"@babel/core": "^7.12.9",
"@types/react": "~17.0.21",
"@types/react-native": "~0.66.13",
"typescript": "~4.3.5"
},
"private": true
}
och med följande App.tsx:
import { StatusBar } from "expo-status-bar";
import { Image, StyleSheet, Text, View } from "react-native";
import { useAssets } from "expo-asset";
export default function App() {
let [assets] = useAssets([require("./assets/icon.png")]);
return (
<View style={styles.container}>
{assets ? <Image source={assets[0]} /> : null}
<StatusBar style="auto" />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
},
});
det nämnda felet visas på rad (10, 24) (på source-egenskapen)
Jag hoppas verkligen att jag har gjort något fel eftersom det för mig verkar som att typdefinitionerna på något sätt är inkompatibla (som i Asset-klassens width-egenskap borde definieras med undefined istället för null), så hur fixar jag detta?
Svar #1
Den korrekta formen är att använda ett objekt med nyckeln uri. Så här:
export default function App() {
let [assets] = useAssets([require("./assets/icon.png")]);
return (
<View style={styles.container}>
{assets ? <Image source={{ uri: assets[0].uri }} /> : null}
<StatusBar style="auto" />
</View>
);
}
Svar #2
Problemet är att TypeScript inte kan härleda typen korrekt från assets[0]. source förväntar sig typen ImageSource så eftersom vi är säkra på typen kan vi helt enkelt kasta den.
import { Image, ImageSource } from "expo-image";
{assets ? (
<Image
source={assets[0] as ImageSource}
style={styles.image}
contentFit="contain"
/>
) : null}
