[英]I can't define type to set an array of objects in a variable React.useState
我正在尝试使用SheetJS库设置来自 an.xlsx 的值。 下面我将介绍代码和错误,以及在我尝试过的 forms 之后不久。
来自var dataToJson 的数据 output :
(6) [{…}, {…}, {…}, {…}, {…}, {…}]
0: {idSeller: 503, idSupplier: 20, financialGoal: 0, positivationGoal: 300, qtVenda: 0, …}
1: {idSeller: 3113, idSupplier: 9, financialGoal: 400000, positivationGoal: 6, qtVenda: 0, …}
2: {idSeller: 7303, idSupplier: 378, financialGoal: 390000, positivationGoal: 0, qtVenda: 0, …}
3: {idSeller: 3113, idSupplier: 964, financialGoal: 360000, positivationGoal: 0, qtVenda: 0, …}
4: {idSeller: 7116, idSupplier: 378, financialGoal: 310000, positivationGoal: 0, qtVenda: 0, …}
5: {idSeller: 7117, idSupplier: 378, financialGoal: 300000, positivationGoal: 0, qtVenda: 0, …}
length: 6
__proto__: Array(0)
对象内的数据:
5:
financialGoal: 300000
idSeller: 7117
idSupplier: 378
positivationGoal: 0
qtVenda: 0
__rowNum__: 6
__proto__: Object
接口和代码:
interface IXlsxData {
financialGoal: number;
idSeller: number;
idSupplier: number;
positivationGoal: number;
qtVenda: number;
// __rowNum__: number;
};
const Archive: React.FC = () => {
const [files, setFiles] = useState<IXlsxData>(null);
const readExcel = (e) => {
e.preventDefault();
var file = e.target.files[0];
var reader = new FileReader();
reader.readAsArrayBuffer(file);
reader.onload = (e) => {
/* Parse data */
let data = e.target.result;
let readedData = XLSX.read(data, {type: 'buffer'});
/* Get first ws (worksheet) */
const wsname = readedData.SheetNames[0];
const ws = readedData.Sheets[wsname];
/* Convert array to json */
const dataToJson = XLSX.utils.sheet_to_json(ws);
setFiles(dataToJson); // ---- ERROR ----
// setFiles([...files, dataToJson]);
};
}
错误:
const dataToJson: unknown[]
Argument of type 'unknown[]' is not assignable to parameter of type 'SetStateAction<IXlsxData[]>'.
Type 'unknown[]' is not assignable to type 'IXlsxData[]'.
Type '{}' is missing the following properties from type 'IXlsxData': financialGoal, idSeller, idSupplier, positivationGoal, qtVendats(2345)
我已经尝试了几种方法:
interface IXlsxData {
[index: number]: {
financialGoal: number;
idSeller: number;
idSupplier: number;
positivationGoal: number;
qtVenda: number;
};
}
和这个:
interface IXlsxProps extends Array<IXlsxData> {};
const [files, setFiles] = useState<IXlsxProps>([]);
IXlsxData
的这个定义很好:
// you dont have to include ALL the existing fields here
// just the ones you're going to use later in the code
interface IXlsxData {
financialGoal: number;
idSeller: number;
idSupplier: number;
positivationGoal: number;
qtVenda: number;
};
但是,如果您期望这些值的数组(我可以通过第一个日志猜到),则必须像这样注释useState
:
const [files, setFiles] = useState<IXlsxData[]>([]);
现在到了真正的问题。 问题是XLSX.utils.sheet_to_json(ws)
返回一个类型为unknown[]
的值,但您的setFiles
期望一个类型为IXlsxData[]
的值。 现在您有几个选项可以确保编译器从sheet_to_json
返回的结果是所需的类型:
function isIXlsxData(data: unknown): data is IXlsxData {
return (data != null)
&& (typeof data === 'object')
&& (typeof (data as IXlsxData).financialGoal === 'number')
&& (typeof (data as IXlsxData).idSeller === 'number')
&& (typeof (data as IXlsxData).idSupplier === 'number')
&& (typeof (data as IXlsxData).positivationGoal === 'number')
&& (typeof (data as IXlsxData).qtVenda === 'number');
}
function isArrayOfIXlsxData(data: unknown): data is IXlsxData[] {
if (!Array.isArray(data)) return false;
return data.every(isIXlsxData);
}
const dataToJson = XLSX.utils.sheet_to_json(ws);
if (isArrayOfIXlsxData(dataToJson)) {
setFiles(dataToJson);
} else {
// handle error
}
虽然类型保护给您一个简单的回答yes
或no
的问题:该unknown[]
类型实际上是否是您的IXlsxData[]
。 断言 function 可能会为您提供有关究竟出了什么问题的更多信息:
function assertIXlsxData(data: unknown): asserts data is IXlsxData {
if (data == null) {
throw new Error('IXlsxData assert failed: value is null');
}
if (typeof data !== 'object')
throw new Error('IXlsxData assert failed: value is not an object');
const errors: string[] = [];
(['financialGoal',
'idSeller',
'idSupplier',
'positivationGoal',
'qtVenda',
] as const).forEach((prop) => {
if (typeof (data as IXlsxData)[prop] !== 'number') {
errors.push(`property ${prop} must be a number`);
}
})
if (errors.length > 0)
throw new Error(`IXlsxData assert failed: ${errors.join(', ')}`)
}
function assertArrayOfIXlsxData(data: unknown): asserts data is IXlsxData[] {
if (!Array.isArray(data))
throw new Error('IXlsxData[] assert failed. Data is not an array');
data.forEach(assertIXlsxData);
}
const dataToJson = XLSX.utils.sheet_to_json(ws);
try {
assertArrayOfIXlsxData(dataToJson);
setFiles(dataToJson);
} catch (ex) {
// handle error
}
IXlsxData[]
没有其他任何东西来自此sheet_to_json(ws)
调用,只需强制编译器相信您:const dataToJson = XLSX.utils.sheet_to_json(ws) as IXlsxData[];
setFiles(dataToJson);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.