#javascript #reactjs #typescript #jsx
Вопрос:
Я запускаю этот код и только что увидел, как появилась эта ошибка.
import { ethers } from 'ethers'
import { getMulticallContract } from 'utils/contractHelpers'
import { MultiCallResponse } from './types'
export interface Call {
address: string // Address of the contract
name: string // Function name on the contract (example: balanceOf)
params?: any[] // Function params
}
interface MulticallOptions {
requireSuccess?: boolean
}
const multicall = async <T = any>(abi: any[], calls: Call[]): Promise<T> => {
try {
const multi = getMulticallContract()
const itf = new ethers.utils.Interface(abi)
const calldata = calls.map((call) => [call.address.toLowerCase(), itf.encodeFunctionData(call.name, call.params)])
const { returnData } = await multi.aggregate(calldata)
const res = returnData.map((call, i) => itf.decodeFunctionResult(calls[i].name, call))
return res
} catch (error) {
throw new Error(error)
}
}
Это ошибка, которую я получаю, хотя до сих пор это работало просто отлично.
Argument of type 'unknown' is not assignable to parameter of type 'string'. TS2345
28 | return res
29 | } catch (error) {
> 30 | throw new Error(error)
| ^
31 | }
32 | }
33 |
Я просмотрел связанные с этим вопросы, но не вижу точного решения в этом случае, но в настоящее время я изучаю машинопись.
Комментарии:
1. Что делать, если вы просто «выдадите ошибку» вместо «выдадите новую ошибку(ошибку)»
2. В чем именно заключается смысл этого
catch
пункта? Какого родаerror
вы ожидаете от кода вtry
блоке?
Ответ №1:
В подобном случае вы никогда не узнаете, какой тип ошибки будет выдан( unknown
), и new Error()
получите строку
Основываясь на контексте вашей multicall
функции, я бы посоветовал вам поместить значимую строку в эту ошибку (что обычно делают веб-сайты производственного уровня).
Вы бы бросили что-то вроде этого:
const multicall = async <T = any>(abi: any[], calls: Call[]): Promise<T> => {
try {
const multi = getMulticallContract();
const itf = new ethers.utils.Interface(abi);
const calldata = calls.map((call) => [
call.address.toLowerCase(),
itf.encodeFunctionData(call.name, call.params),
]);
const { returnData } = await multi.aggregate(calldata);
const res = returnData.map((call, i) => itf.decodeFunctionResult(calls[i].name, call));
return res;
} catch {
throw new Error('something went wrong in the multical function');
}
};
Ответ №2:
В конце концов я просто добавил "useUnknownInCatchVariables": false,
в tsconfig, и это предотвратило преобразование ошибок в неизвестные, что и стало причиной этой проблемы.
Я думаю, что мне также нужно обновить typescript, потому что в tsconfig есть предупреждение об этом флаге Unknown compiler option 'useUnknownInCatchVariables'.
Также обратите внимание, что в документах упоминается другое решение этой проблемы: https://www.typescriptlang.org/tsconfig#useUnknownInCatchVariables
try {
// ...
} catch (err) {
// We have to verify err is an
// error before using it as one.
if (err instanceof Error) {
console.log(err.message);
}
}
Комментарии:
1. Вам действительно не следует отключать проверку, а лучше исправить свой код. Возможно, если
Error
был выдан экземпляр, ваш вызовnew Error(error)
был прерван.2. Вы читали это: typescriptlang.org/tsconfig#useUnknownInCatchVariables Первая строка.. В TypeScript 4.0 была добавлена поддержка, позволяющая изменять тип переменной в предложении catch с любого на неизвестный. Тип переменной изменился, до этого вызов ошибки работал просто отлично.
3. Нет, код не сработал. Да, компилятор не жаловался и теперь жалуется, но передача
Error
экземпляра в качестве аргументаnew Error
является неправильной независимо от того, какую версию Typescript вы используете.