我正在使用 yup 来验证表单,并且在尝试使此 catch 工作时遇到了此类型错误:
第 1196 章
我的代码:
const handleSubmit = async (): Promise<void> => {
try {
const isValid = await userSchema.validate(values, { abortEarly: false });
console.log(isValid);
} catch (err: ValidationError) {
console.log(err);
const errors = getValidationErrors(err);
}
Run Code Online (Sandbox Code Playgroud)
getValidationErrors 函数:
export function getValidationErrors(err: yup.ValidationError): Errors {
console.error(err);
const validationErrors: Errors = {};
err.inner.forEach((error) => {
if (error.path) validationErrors[error.path] = error.message;
});
return validationErrors;
}
Run Code Online (Sandbox Code Playgroud)
在搜索它时,我发现 Typescript 不接受子句 catch 参数的类型......这是为什么?这在 Java 或其他语言中很常见...我的意思是...我的解决方案是 attribute err: any...但是 type any 不是永远不会使用的东西吗?
Nic*_*wer 124
Typescript 不允许您这样做,因为 Typescript 无法在编译时验证代码唯一可以抛出的问题是 ValidationError。就此而言,您也不知道:如果由于超出了最大调用堆栈而收到 RangeError 该怎么办?显然这是不可能的(在调用它之前你必须建立一个大的调用堆栈),但是这段代码不能保证它不会发生。
如果您希望错误具有某种类型,则需要添加代码来验证它实际上是该类型:
catch (err: unknown) {
if (err instanceof ValidationError) {
// Inside this block, err is known to be a ValidationError
}
}
Run Code Online (Sandbox Code Playgroud)
或者你需要使用类型断言来告诉打字稿“我知道它是这种类型,相信我”:
catch (err: unknown) {
getValidationErrors(err as ValidationError);
}
Run Code Online (Sandbox Code Playgroud)
// or:
catch (err: unknown) {
const knownError = err as ValidationError;
getValidationERrors(knownError);
}
Run Code Online (Sandbox Code Playgroud)
这在 Java 或其他语言中很常见......
不同的语言对其设计有不同的限制。例如,在 Java 中,您可以定义函数将抛出哪些错误作为函数定义的一部分,如
public static FileInputStream example(String fileName) throws FileNotFoundException {
Run Code Online (Sandbox Code Playgroud)
javascript 和 typescript 都无法在函数定义中指定这一点。
java 允许你有多个 catch 块,不同类型的错误由不同的错误处理,但由于 typescript 仅在编译时存在,所以这不是一个选项。一切都必须在单个 catch 块中处理,并且必须使用显式代码来区分正在处理的错误类型。
kay*_*ya3 15
您无法在 Typescript 中为子句变量编写特定的注释catch,因为在 Javascript 中,catch子句将捕获引发的任何异常,而不仅仅是指定类型的异常。
Java 允许你(实际上,要求你)编写异常的类型,因为在编译时它能够检查(对于已检查的异常类型)是否可以抛出该异常,但更重要的是,在运行时它会检查什么类型抛出异常,并且仅catch当异常类型与catch子句匹配时才捕获它(执行块)。
在 Typescript 中,如果你只想捕获特定类型的异常,则必须捕获抛出的任何异常,检查它是否是你想要处理的异常类型,如果不是,则再次抛出:
try {
// code that could throw ValidationError
} catch(e: unknown) {
if(!(e instanceof ValidationError)) { throw e; }
// code to handle ValidationError
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,在if语句之后,e的类型将缩小为ValidationError并且您可以访问e.message.
小智 11
正如其他人所指出的,TS 不允许您在 catch 子句中使用“any”或“unknown”以外的类型。
但是,您可以将错误变量转换为特定类型。使用 myVariable.
try {
// where some ValidationError object could be thrown
} catch (err: unknown) {
const errors = getValidationErrors(<ValidationError>err);
}
Run Code Online (Sandbox Code Playgroud)
根据这篇Typescript 文档,在 TS 4.0 版本之前,catch 子句参数通常键入为any,并且在处理第一个参数时可能会导致新的错误。
例子:
try {
// Do something
} catch (x) {
console.log(x.message);
}
Run Code Online (Sandbox Code Playgroud)
如果没有message房产怎么办x?是的,现在你有一个新的错误。
unknowntype 作为 的安全替代方案而存在any,因为类型操作unknown是非法的,因此您必须unknown在执行任何操作之前对变量进行类型检查。
另外根据文档,类型any:
缺乏任何类型安全,可能会因无效操作而出错。
因此我们可以得出结论,您应该继续避免使用any.
希望我的回答对你有帮助。
| 归档时间: |
|
| 查看次数: |
75825 次 |
| 最近记录: |