Kev*_*ker 6 javascript generator typescript axios mobx-state-tree
我使用 Axios 来处理一些 API 获取,并且在生成器中执行该调用;async/await
不是这个特定项目的选择。由于某种原因,即使axios
我的类型正确,any
当我使用yield
关键字时,打字稿也会推断出类型。
function* foo() {
// axios.get is returning Promise<AxiosResponse<T>>
// but data is being inferred as "any"
const { data } = yield axios.get<T>(url);
// do some stuff with data
}
Run Code Online (Sandbox Code Playgroud)
如果我专门输入 axios 响应,它工作正常,但我觉得我错过了一些东西,因为 TS 不会自动获取类型
function* foo() {
const { data }: AxiosResponse<T> = yield axios.get<T>(url);
// do some stuff with data
}
Run Code Online (Sandbox Code Playgroud)
我还缺少其他步骤或配置吗?
这是我的 tsconfig
function* foo() {
// axios.get is returning Promise<AxiosResponse<T>>
// but data is being inferred as "any"
const { data } = yield axios.get<T>(url);
// do some stuff with data
}
Run Code Online (Sandbox Code Playgroud)
TypeScript 无法推断yield
操作的类型,因为它是由调用代码控制的。在您的情况下,听起来这个生成器正在被处理 axios 承诺的代码使用,并通过在调用中提供 axios 结果来响应g.next
。如果您处于无法使用async
/ 的环境中,这是有道理的await
;next
生成器可用于允许异步逻辑更清晰地流动,其中生成器由助手驱动,该助手从生成器获取承诺,等待它解决,然后通过\xc2\xa0\将履行值传递回生成器xe2\x80\x94在执行此操作时yield
很大程度上扮演了 的角色await
。(这是支持以这种方式使用生成器的库的一个示例。)因此使用co
生成器的代码期望生成器生成 a并返回承诺的履行值。在这种情况下,这将产生一个并返回一个Promise
Promise<AxiosResponse<T>>
AxiosResponse<T>
。
为了处理这个问题,您需要使用类型来注释该函数Generator
,该类型接受三个类型参数:
T
- 生成器通过生成的类型yield
。TReturn
- 生成器完成后返回的类型。TNext
- 生成器消耗的类型(从 接收yield
)。因此,将其应用到您的示例中,我们将添加一个泛型类型参数foo
并用以下注释对其进行注释Generator
:
function* foo<T>(): Generator<Promise<AxiosResponse<T>>, ReturnType, AxiosResponse<T>> {\n const { data } = yield axios.get<T>(url); \n \n // ...do some stuff with data...\n\n return /*...something of `ReturnType` (or use `void` as the type argument above)... */;\n}\n
Run Code Online (Sandbox Code Playgroud)\n对于那些不太熟悉yield
生成器的人来说,这里有一个示例,其中生成器生成字符串,返回布尔值,并使用数字(游乐场链接):
function* example(): Generator<string, boolean, number> {\n const a = yield "a";\n console.log(`Received ${a} for a`);\n const b = yield "b";\n console.log(`Received ${b} for b`);\n const c = yield "c";\n console.log(`Received ${c} for c`);\n const flag = (a + b) > c;\n return flag;\n}\n\nconst g = example();\nlet result = g.next();\nconsole.log(result.value); // "a"\nresult = g.next(1); // Passes 1 to the generator\n// (Generator logs "Received 1 for a")\nconsole.log(result.value); // "b"\nresult = g.next(2); // Passes 2 to the generator\n// (Generator logs "Received 2 for b")\nconsole.log(result.value); // "c"\nresult = g.next(3); // Passes 3 to the generator\n// (Generator logs "Received 3 for c")\nconsole.log(result.value); // false (1 + 2 > 3 is false)\n
Run Code Online (Sandbox Code Playgroud)\n