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 init och väljer blank (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}

Relaterade artiklar