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 次 |
最近记录: |