这是Typescript: interface that extends a JSON type的扩展
给定如下JSON类型:
type JSONValue =
| string
| number
| boolean
| null
| JSONValue[]
| {[key: string]: JSONValue}
我想找到一种方法告诉typescript,当与JSONType匹配的接口被传递到接受JSONType的函数时,它应该被自动转换。
interface Foo {
name: 'FOO',
fooProp: string
}
const bar = (foo: Foo) => { return foo }
const wrap = (fn: (...args: JSONValue[]) => JSONValue, args: JSONValue[]) => {
return fn(...args);
}
wrap(bar, {name: 'FOO', fooProp: 'hello'});
当前此操作失败,原因是:
Argument of type '(foo: Foo) => Foo' is not assignable to parameter of type '(...args: JSONValue[]) => JSONValue'.
Types of parameters 'foo' and 'args' are incompatible.
Type 'JSONValue' is not assignable to type 'Foo'.
Type 'null' is not assignable to type 'Foo'.
即使通过分析我们知道传入的foo是JSON兼容类型。
这里是Playground
有没有办法让typescript识别出这个接口实际上也是JSON?
1条答案
按热度按时间eqqqjvef1#
您的实作目前有多个问题。您尝试输入函式
wrap
,就好像它会接受函式fn
,而该函式可能会传入任意JSONValue[]
数据。但是您会传入bar
,而该函式 * 只 * 接受Foo
。若要修正此问题,我们可以使wrap
在T
上泛型化,其中T
表示fn
的参数。然后,我们将args
类型也输入为T
,以便可以安全地将args
传递给fn
。注意我是如何将
args
作为一个 *spread参数 * 的,我们不希望args
是一个元组类型,因为在调用它时,你不会将元组传递给函数。但是这仍然不起作用。
Foo
当前是一个没有隐式索引签名的interface
(请参阅#15300)。interface
无法满足{[key: string]: JSONValue}
条件约束,因为缺少这个隐含索引签章。唯一不需要扩大JSONValue
型别的解决方法是将Foo
转换为type
。Playground