按照 expo-asset 文档提供的小示例,将资产数组中的元素传递到 Image
source
属性会出现以下打字稿错误:
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>'
我在 macOS 上使用 Node 版本 16.15.0、Yarn 版本 1.22.18 和 expo-cli 版本 5.4.7。
该问题可通过以下方式重现:
expo init
初始化新项目并选择 blank (Typescript)
模板expo install expo-asset
package.json
看起来像这样(删除脚本以便于阅读):
{
"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
}
并具有以下
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",
},
});
提到的错误显示在第 (10, 24) 行(在
source
属性上)
我真的希望我做错了什么,因为在我看来,类型定义在某种程度上是不兼容的(如在
Asset
类中' width
属性应该用 undefined
而不是 null
定义),那么我该如何解决这个问题呢?
正确的形式是使用带有
uri
键的物体。
像这样:
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>
);
}
问题是 typeScript 无法从
assets[0]
正确推断类型。 source
需要 ImageSource
类型,因此我们对类型有信心,我们可以简单地转换它。
import { Image, ImageSource } from "expo-image";
{assets ? (
<Image
source={assets[0] as ImageSource}
style={styles.image}
contentFit="contain"
/>
) : null}