React+TypeScript开发文件上传组件时,为状态中的文件对象定义类型遭遇类型不兼容错误求助
解决React+TypeScript文件上传组件的状态类型错误
我刚帮你排查了这个TypeScript错误,问题出在状态的类型定义和初始值不匹配上,咱们一步步来修复:
1. 修正状态的类型定义
你当前的状态初始化代码是:
const [selectedFiles, setSelectedFiles] = useState<File>(null);
这里泛型参数File表示状态只能是File类型,但你给的初始值是null,TypeScript自然会抛出类型不兼容的错误。咱们需要把状态类型改成允许null:
const [selectedFiles, setSelectedFiles] = useState<File | null>(null);
这样TypeScript就知道selectedFiles可以是File对象或者null,完全符合组件初始无文件的场景。
2. 处理文件选择时的可选链结果
event?.target?.files?.[0]可能返回undefined(比如用户打开文件选择框后又取消),咱们可以用空值合并运算符??把它转成null,确保和状态类型一致:
const handleFileSelect = (event: React.ChangeEvent<HTMLInputElement>) => { const selectedFile = event.target.files?.[0] ?? null; setSelectedFiles(selectedFile); };
3. 优化acceptedFormats的类型定义
你当前的acceptedFormats类型写的是string | AcceptedFileType[],但实际上不管输入是字符串还是数组,最后都会通过join(",")转成字符串,所以直接把类型定义为string更准确:
const acceptedFormats: string = typeof fileType === "string" ? fileType : Array.isArray(fileType) ? fileType.join(",") : AcceptedFileType.Text;
完整修复后的代码
import * as React from "react"; import { Button } from "@material-ui/core"; import { useState } from "react"; interface UploaderProps { fileType?: string | AcceptedFileType[]; } enum AcceptedFileType { Text = ".txt", Gif = ".gif", Jpeg = ".jpg", Png = ".png", Doc = ".doc", AllImages = "image/*", AllVideos = "video/*", AllAudios = "audio/*" } export const Upload = (props: UploaderProps): JSX.Element => { const { fileType } = props; const acceptedFormats: string = typeof fileType === "string" ? fileType : Array.isArray(fileType) ? fileType.join(",") : AcceptedFileType.Text; const [selectedFiles, setSelectedFiles] = useState<File | null>(null); const handleFileSelect = (event: React.ChangeEvent<HTMLInputElement>) => { const selectedFile = event.target.files?.[0] ?? null; setSelectedFiles(selectedFile); }; const onUpload = () => { // eslint-disable-next-line no-console console.log(selectedFiles); }; return ( <> <Button variant="contained" component="label" style={{ textTransform: "none" }} > <input hidden type="file" accept={acceptedFormats} onChange={handleFileSelect} /> <span> Choose file to upload</span> </Button> <Button color="primary" disabled={!selectedFiles} style={{ textTransform: "none" }} onClick={onUpload} > Upload </Button> </> ); };
这样修改后,TypeScript的错误就会消失,同时代码的类型安全性也得到了保障。
内容的提问来源于stack exchange,提问作者user16860065
相关产品推荐
相关产品推荐

