我正在尝试将以下Flow片段转换为Typescript:
type Handler<Data> = (data: Data) => void
type Foo = { foo: string }
type AnyRequest = (path: '/foo', handler: Handler<Foo>) => void
type FooRequest = (path: string, handler: Handler<any>) => void
type RouterRequest = AnyRequest | FooRequest
function router(request: RouterRequest) {
request('/foo', (data) => {
// here data should be of type Foo
})
request('/bar', (data) => {
// here data should be of type any
})
}
此处的流程可以使用data
参数正确推断出path
的类型。见running snippet
Typescript中的相同代码无法推断出data
的类型
在playground中粘贴此代码会给我这个错误
无法调用类型缺少调用签名的表达式。输入&#39; RouterRequest&#39;没有兼容的呼叫签名。
有没有办法在Typescript中实现类似的东西?
答案 0 :(得分:2)
我认为你的意思是RouterRequest
是AnyRequest
和FooRequest
的交集,而不是他们的 union < / em>的。像这样:
type RouterRequest = AnyRequest & FooRequest;
类型AnyRequest | FooRequest
指的是您不知道它是AnyRequest
还是FooRequest
的内容。 TypeScript或多或少警告你它不知道它是哪一个所以它根本不会让你调用它(虽然它可能should让你用参数的交集调用它,但是我离题。)
但是你希望能够用任何一组参数来调用它。这更像是overloaded function(或函数类型的交集)而不是联合。
如果您更改上面的行,它应该适合您,假设RouterRequest
确实可以通过两种方式调用。
希望有所帮助;祝你好运!
答案 1 :(得分:2)
这是RouterRequest
类型,允许完整的上下文输入...
type RouterRequest = {
(path: "/foo", handler: Handler<Foo>): void;
(path: string, handler: Handler<any>): void;
}
完整示例:
type Handler<Data> = (data: Data) => void;
type Foo = { foo: string }
type RouterRequest = {
(path: "/foo", handler: Handler<Foo>): void;
(path: string, handler: Handler<any>): void;
}
function router(request: RouterRequest) {
request('/foo', (data) => {
// data is of type Foo
})
request('/bar', (data) => {
// data is of type any
})
}
答案 2 :(得分:0)
这将有效:
type RouterRequest = {
(path: '/foo', handler: Handler<Foo>) :void
(path: string, handler: Handler<any>):void;
}