我想做的是包装fetch
函数以处理一些fetch
样板文件,例如call .json()
。
但问题是,如果我将fetch
函数包装在一个带有我自己注释的函数中,我会失去很多类型安全性,因为我的类型永远不会像默认情况下 Flow 附带的类型那样具体。
所以我尝试利用存在类型(*)
并typeof
让 Flow 保留默认注释
// Imported as f because importing as "fetch"
// overwrites all of Flow's default type info about fetch
import f from 'node-fetch'
export const fetchJSON: typeof fetch =
(url: *, opts: *): * => f(url, opts).then(r => r.json())
export const post: typeof fetchJSON = (url: *, opts: *): * => fetchJSON(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
...opts
})
不幸的是,这给了我一些没有多大意义的类型错误
10: export const post: typeof fetchJSON = (url: *, opts: *): * => fetchJSON(url, {
^ object literal
11: method: 'POST',
^^^^^^ string. This type is incompatible with
824: method?: ?MethodType;
^^^^^^^^^^^ null. See lib: /private/tmp/flow/flowlib_22594590/bom.js:824
x.js:10
10: export const post: typeof fetchJSON = (url: *, opts: *): * => fetchJSON(url, {
^ object literal
12: headers: { 'Content-Type': 'application/json' },
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ object literal. This type is incompatible with
822: headers?: ?HeadersInit;
^^^^^^^^^^^^ null. See lib: /private/tmp/flow/flowlib_22594590/bom.js:822
x.js:10
10: export const post: typeof fetchJSON = (url: *, opts: *): * => fetchJSON(url, {
^ object literal
12: headers: { 'Content-Type': 'application/json' },
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ property `Content-Type`. Property not found in
822: headers?: ?HeadersInit;
^^^^^^^^^^^ Headers. See lib: /private/tmp/flow/flowlib_22594590/bom.js:822
Found 3 errors
有什么办法可以使这项工作?
我能够用更大问题的一个小得多的子集重现这个问题,我想我现在理解了这个问题,因为它与fetch
自身完全无关。
// @flow
const opts: RequestOptions = {}
const test = { method: 'POST', headers: { 'Content-Type': 'application/json' }, ...opts }
上面会导致类似的错误,这是因为传播opts
到对象中可能会重写'POST'
为null
,这是不允许的,因为它具有string
类型。解决方案是扩展到一个新对象,而不是现有对象。所以
const test = { ...{ method: 'POST', headers: { 'Content-Type': 'application/json' } }, ...opts }
将工作。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句