TypeScript 用于将Promise.catch变量类型确定为未知的标志

j7dteeu8  于 2022-10-29  发布在  TypeScript
关注(0)|答案(8)|浏览(320)

建议

可行性检查表

我的建议符合以下准则:

  • 这不会是对现有TypeScript/JavaScript代码的重大更改
  • 这不会改变现有JavaScript代码的运行时行为
  • 这可以在不基于表达式的类型发出不同JS的情况下实现
  • 这不是一个运行时特性(例如,库功能、带JavaScript输出的非ECMAScript语法、JS的新语法糖等)
  • 此功能与TypeScript's Design Goals的其余部分一致。

建议

#41016之后添加了一个标志,以将catch变量视为unknown
为了保持一致性,并且由于它们是类似的情况,我建议还添加一个标志,用于对promises的.catch回调执行此操作。
另请参阅:eslint-plugin-etc/no-implicit-any-catch

r55awzrz

r55awzrz1#

.catch(...)回调参数的类型是在lib文件中定义的,所以我们必须公开一个新的类型,根据编译设置,它的行为类似于unknownany ......我不确定我们是否希望该类型转义到wild中😬。

bvn4nwqk

bvn4nwqk2#

通过在项目中重载Promise.catch的签名,可以轻松实现这一点

// Promise.d.ts
interface Promise<T> {
  /**

* Attaches a callback for only the rejection of the Promise.
* @param onrejected The callback to execute when the Promise is rejected.
* @returns A Promise for the completion of the callback.
* /

  catch<TResult = never>(
    onrejected?: ((reason: unknown) => TResult | PromiseLike<TResult>) | undefined | null,
  ): Promise<T | TResult>;
}
qc6wkl3g

qc6wkl3g3#

@Cellule谢谢你的代码片段,是的,你可以自己做,但是这个建议的目标是把这个添加到TS本身

dffbzjpn

dffbzjpn4#

@Cellule谢谢你!不幸的是它没有覆盖allSettled,我无法覆盖它:

interface PromiseRejectedResult {
  status: "rejected";
  // @ts-expect-error TS2717 even if overridden, it doesn't work
  reason: unknown;
}

https://www.typescriptlang.org/play?target=7#code/IYZwngdgxgBAZgV2gFwJYHsIwG4FMBOYehEqUuAFAJQwDeAUDEzFJiMjAA77oC2qIXCBgBeGMADuwVBwAKPfoIB0wADaqAyrmTJVuACYUA2gEYAulUbM46fDAqsI7LgoG4Y6OC75uQNBszMqF4U3D7K7MDICMIicTAARPi4AFa4UMgGCf5WgUxhirhKyaCYucwAvuVVFUA

qyswt5oh

qyswt5oh5#

您可以通过在项目中重载Promise.catch的签名来轻松实现这一点
我试过了,但是如果签名不匹配,TS似乎只选择了'any'重载。Playground

2lpgd968

2lpgd9686#

我真的很想看到这个实现,我认为很遗憾它没有被考虑和useUnknownInCatchVariables一起发布。

  • p.then(good, bad)
  • p.then(good).catch(bad),以及
  • try { result = await p; good(result) } catch (err) { bad(err); }(在async上下文中)

现在,如果bad不期望unknown,它将失败,但仅在这些形式的最后一种中。我需要一个标志,它表示“对所有错误使用unknown类型”,包括try/catch和Promise拒绝--它们是相同的,在async/await下!

gdrx4gfi

gdrx4gfi7#

@thw0rted(返回)

  • x1m0n1x
  • p.then(good).catch(bad)

是不一样的,因为如果good抛出错误,只有后一种形式会捕获它。
p => p.then(good, bad)实际上相当于:

async p => {
	let result;
	try {
		result = await p;
	} catch (err) {
		return bad(err);
	}

	return good(result);
}
t98cgbkg

t98cgbkg8#

这是正确的,但我并不是说这些形式是相同的,我只是引用了bad函数的参数类型。关键是then-callback得到any,而catch-block调用得到unknown

相关问题