在导入的模块(jsonrpc-lite)中声明类型时,如何使用类型保护?

时间:2019-04-14 01:20:05

标签: typescript

我正在尝试设置类型保护,以便随后的代码知道对象是某种类型的并且可以推断其属性。但是,我不知道如何引用我要检查的类型。该类型位于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

1 个答案:

答案 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>;