我已经读过打字稿如何扩展inferred types,但仍不确定here的情况:
type Def = {
'T': { status: 5, data: {r: 'm'}},
}
function route<S extends keyof Def>
(route: S, handler: () => Promise<Def[S]>) { }
route('T', async function () {
return { status: 5, data: {r: 'm'} };
});
这在Typescript游乐场中可以很好地工作,但是不应该引发错误,因为Typescript将route()
的第二个参数的类型推断为() => {status: number, data: {r: string}}
?
我问,因为我遇到this code的问题。传递给Router::get
的函数被推断为() => {status: number}
而不是() => {status: 200}
。奇怪的是,删除POST
路由(shown here)时不会出现错误。
答案 0 :(得分:1)
这个简单的示例确实按预期工作,并且此处不会发生字面量类型扩展-函数route()
是泛型的,并且首先推断S
是因为您在调用它时未指定其泛型类型参数{ {1}}:
S
因此,首先,编译器必须根据传递的实际参数的类型来推断route('T', async function () {
return { status: 5, data: {r: 'm'} };
});
。
通过查看第一个参数文字S
,它将确定'T'
为文字类型S
。
因此,第二个参数'T'
的返回类型立即固定为定义为() => Promise<Def[S]>
的对象文字类型。然后,编译器无需推断异步函数的返回类型,只需检查其是否符合Def['T']
(确实如此)。
为什么不起作用,in this, more complex code我不知道,但是我怀疑Def['T']
中的索引签名会阻止类型推断对ApiDefBase
的影响-如果您添加类似的索引签名到简单的示例,您将开始遇到相同的错误:
Path
现在,为什么添加索引签名会对类型推断产生这种影响-我不知道。