我正在尝试设置类型保护,以便随后的代码知道对象是某种类型的并且可以推断其属性。但是,我不知道如何引用我要检查的类型。该类型位于npm模块(jsonrpc-lite)中。
如何在类型保护中引用类型?
我正在使用3.2版打字稿。请注意:我是打字稿新手!
第一次尝试(不使用类型防护):
// somefile.ts
import * as jsonrpc from "jsonrpc-lite"
export const foo = (
req: express.Request,
res: express.Response,
next: express.NextFunction
) => {
const payload = jsonrpc.parseObject(req.body).payload // fine!
console.log(payload.id) // Fails!
// Gives me: Property 'id' does not exist on type 'SuccessObject | NotificationObject | RequestObject | ErrorObject | JsonRpcError'
// ...
}
第二次尝试:
我知道,如果类型为id
,则有效负载上可以使用RequestObject
属性,因此我认为可以使用类型保护来扩充代码。
我认为RequestObject
类型必须首先对类型系统可见,因为它说Property 'id' does not exist on type 'SuccessObject | NotificationObject | RequestObject | ErrorObject | JsonRpcError'
但是,我不知道如何在类型保护中引用jsonrpc-lite RequestObject
-请参阅下面的问号。
// My type guard
// The problem is that I don't know what to write in place of ??????.
// I want to reference jsonrpc-lite's RequestObject type:
const isRequestObj = (payload: any): payload is ?????? => {
return true
}
这是jsonrpc-lite的d.ts文件:https://github.com/teambition/jsonrpc-lite/blob/master/jsonrpc.d.ts
答案 0 :(得分:1)
首先,最好的解决方案是说服程序包的开发人员导出所有重要类型。因为对该软件包的任何更新都可能导致其他解决方案停止工作。
下一个最佳解决方案是进行结构类型匹配,并仅区分您真正使用的那些属性:
const hasId = (payload: any): payload is { id: string } =>
typeof payload === 'object' && typeof payload.id === 'string';
但是由于问题实际上是关于检索类型的,所以这里是执行该操作的方法,甚至认为它可能无法使用更新进行工作:
type payload = ReturnType<typeof jsonrpc.parseObject>["payload"];
type matchRequest<T> = T extends {
id: string | number;
method: string;
params?: object;
} ? T : never;
type RequestObject = matchRequest<payload>;