Rum*_*nsk 14 yield call typescript redux-saga
如何使用 设置函数的类型call()?
我有这个功能:
export function apiFetch<T>(url: string): Promise<T> {
return fetch(url).then(response =>
{
if (!response.ok) throw new Error(response.statusText)
return response.json().then(data => data as T);
}
)
}
Run Code Online (Sandbox Code Playgroud)
这个函数可以像这样使用:
let resp = await apiFetch<ServerResponse>("http://localhost:51317/Task");
Run Code Online (Sandbox Code Playgroud)
通过使用您在上面的代码段中看到的函数,它resp是正确的字符串类型。所以智能感知为我提供了ServerResponse界面的所有属性。
但是,必须在redux-saga不允许的工人内部调用此函数,异步函数:
function* refreshTaskSaga():any {
yield takeEvery("TASK_REFRESH", workerRefreshTaskSaga);
}
function* workerRefreshTaskSaga() {
//I need to call the function here
}
Run Code Online (Sandbox Code Playgroud)
我尝试使用 yield + call 调用它,如redux-saga文档所述:
a) let resp = yield call(apiFetch, "http://localhost:51317/Task");
b) let resp = yield call(apiFetch<ServerResponse>, "http://localhost:51317/Task");
Run Code Online (Sandbox Code Playgroud)
第一个选项,按预期执行函数,但是resp有any类型。第二个选项让我感到异常。
No overload matches this call.
The last overload gave the following error.
Argument of type 'boolean' is not assignable to parameter of type '{ context: unknown; fn: (this: unknown, ...args: any[]) => any; }'.ts(2769)
effects.d.ts(499, 17): The last overload is declared here.
Run Code Online (Sandbox Code Playgroud)
知道正确的语法来调用它并且不丢失类型吗?
Nic*_*wer 17
不幸的是, a 的左侧yield 总是有 type any。这是因为原则上可以使用任何值恢复生成器函数。Redux saga 在运行生成器时以可预测的方式运行,但没有什么能阻止某人编写其他代码来逐步完成您的 saga 并为您提供与您产生的内容无关的值,如下所示:
const iterator = workerRefreshTaskSaga();
iterator.next();
// You might have been expecting a ServerResponse, but too bad, you're getting a string.
iterator.next('hamburger');
Run Code Online (Sandbox Code Playgroud)
只有当您可以假设 redux saga 正在运行您的生成器时,您才能对类型进行预测,并且 typescript 无法说“假设此生成器将由 redux saga 运行(以及包括的所有含义)”。
所以你需要自己添加类型。例如:
const resp: ServerResponse = yield call(apiFetch, 'url');
Run Code Online (Sandbox Code Playgroud)
这确实意味着您有责任使类型正确。由于打字稿只能告诉它是一个any,因此无论您说什么类型,它都会信任您。因此 typescript 可以验证此后的代码是否与 a 正确交互ServerResponse,但如果它实际上不是 a ServerResponse,则 typescript 无法向您指出这一点。
为了获得更多的类型安全性ReturnType,我经常做的一件事是 use ,例如:
const output: ReturnType<typeof someFunction> = yield call(someFunction);
Run Code Online (Sandbox Code Playgroud)
我仍然要知道这ReturnType<typeof someFunction>是正确的,但假设我这样做了,那么如果有人更改 someFunction 的实现以使其返回不同的内容,则输出的类型将更新以匹配。
| 归档时间: |
|
| 查看次数: |
11045 次 |
| 最近记录: |