基于输入字符串的函数响应类型

时间:2020-09-18 01:58:36

标签: typescript

我正在尝试为比特币json-rpc api编写客户端,并且需要强类型保证。但是,我似乎不容易找到为什么要基于cmd参数的输入来定义call函数的响应类型。

我下面的代码可以正常工作(您可以将最后一行更改为call("getnewaddress").amount,这会出错,但是似乎很冗长。是否有其他编程方式可以做到这一点?

interface RPCResponse {
  getbalance: {
      amount: number
  };
  getnewaddress: {
      address: string
  };
}

type RPCCommand = keyof RPCResponse;

type RPCResponses<T> = 
    T extends "getbalance" ? RPCResponse["getbalance"] :
    T extends "getnewaddress" ? RPCResponse["getnewaddress"] :
    never;

function call<T extends RPCCommand>(cmd: T): RPCResponses<T> {
    
    if (cmd === "getbalance")
        return { amount: 1 } as RPCResponses<T>;

    if (cmd === "getnewaddress")
        return {address: "test"} as RPCResponses<T>;

  throw new Error("never");
}

console.log(call("getnewaddress").address)

1 个答案:

答案 0 :(得分:0)

在TypeScript中,您可以使用Function Overloading在一个函数上具有多个签名。

此代码相对简单,但提供了强大的类型保证。

interface RPCResponseBalance {
    amount: number;
}

interface RPCResponseAddress {
    address: string;
}


function call(cmd: 'getbalance'): RPCResponseBalance;
function call(cmd: 'getnewaddress'): RPCResponseAddress;
function call(cmd: unknown) {
    if (cmd === "getbalance")
        return { amount: 1 }

    if (cmd === "getnewaddress")
        return { address: "test" }

    throw new Error("never");
}

console.log(call("getnewaddress").address)

Playground