gpt4 book ai didi

typescript - 没有第三方库的类型安全错误处理

转载 作者:行者123 更新时间:2023-12-03 07:38:40 24 4
gpt4 key购买 nike

我知道在 ts 中没有类型安全错误处理的原因是因为我们缺少 throws来自函数的子句。因此,每当我这样做时:

function mighThrow(input: number): void {
if (input === 1) {
throw new TypeError('cannot be one')
} else if(input === 2) {
throw new SyntaxError('invalid syntax: 2')
}
console.log('all good', input)
}

我无法通过准确打字来捕捉错误:
try {
mighThrow(1)
} catch(e) {
// e is any, even though it could be TypeError | SyntaxError
}

问题与 Promise 相同s,捕获器函数参数是硬编码的 any :
interface Promise<T> {
then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): Promise<TResult1 | TResult2>;
catch<TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null): Promise<T | TResult>;
}
catch的论据是任何。

所以 我的问题是 我怎样才能解决这个问题?如果我是图书馆作者,是否有一种类型安全的方法来帮助用户弄清楚他们到底在捕捉什么?我知道一些解决方案,例如添加 Either键入并调用它,但这会强制在现场处理错误,这只会将代码转换为类似于语言已检查异常的内容。

最佳答案

由于目前有 no throws in TypeScript ,任何建议看起来都像是一种解决方法。您正在寻找一种解决方案,它不会为想要忽略错误的用户带来任何开销,但它允许想要捕获错误的用户获得更强的错误类型。

这样的事情怎么样(需要 TS3.1 及更高版本才能工作):

function mighThrow(input: number): void {
if (input === 1) {
throw new TypeError('cannot be one')
} else if (input === 2) {
throw new SyntaxError('invalid syntax: 2')
}
console.log('all good', input);
}
mighThrow.throws = undefined! as TypeError | SyntaxError;

这里我们使用了 function property declaration声明一个名为 throws 的虚拟属性.幻像属性在运行时并不真正存在,但编译器认为它存在,因此编译器会维护额外的类型信息。在这种情况下, undefined! as TypeError | SyntaxError只是 undefined在运行时,但编译器认为 mighThrow有一个 throws类型的属性 TypeError | SyntaxError .

现在,当人们想要捕捉错误时,他们可以使用辅助函数:
type ThrowsType<T> = T extends { throws: infer E } ? E : unknown;
const asTypedError = <FS extends Function[]>(e: any, ...f: FS): ThrowsType<FS[number]> => e;

像这样:
try {
const x = mighThrow(123);
} catch (err) {
const typedErr = asTypedError(mighThrow, err);
// typedErr is now TypeError | SyntaxError
if (typedErr instanceof TypeError) {
typedErr; // TypeError
} else {
typedErr; // SyntaxError
}
}

无论如何它都不完美。它需要错误捕捉器来跟踪哪些函数被自己调用。包含多个函数的 try-catch 块需要将所有这些函数传递给 asTypedError() :
declare const alsoMightThrow: { throws: URIError } & ((input: string) => number);
try {
const x = mighThrow(alsoMightThrow("hey"));
} catch (err) {
const typedErr = asTypedError(err, mighThrow, alsoMightThrow); // 😐
// typedErr: TypeError | SyntaxError | URIError
}

并且实际上并不能保证捕获到的错误属于 throws 中声明的类型。属性......这取决于库维护者是否正确(这很难,因为很多东西在运行时会抛出 TypeError)。相反,大多数函数不会有这样的 throws属性,因此普通开发人员没有太多动机使用这种类型的错误捕获。如果有人输入非 throws那里的功能, asTypedError将输出 unknown 错误,这几乎不比 any 有用.你必须教育图书馆用户如何使用这个东西,在这一点上,只需 document 就更容易了。你的函数和错误捕捉器可以自己做 instanceof检查范围从 any 缩小.这是缺少语言功能的解决方法,看起来像这样。 🤷‍♀️

哦,好吧,希望有帮助。祝你好运!

关于typescript - 没有第三方库的类型安全错误处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52972198/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com