繁体   English   中英

如何将Typescript泛型用于动态函数参数

[英]How can I use typescript generics for dynamic function arguments

我正在尝试围绕节点的gRPC绑定创建包装方法。 我想在WrapperClient上创建一个称为rpc的方法,该方法在基础GrpcClient类上调用一个方法,同时还要对方法请求参数进行类型检查。

这是我将交叉张贴到TS游乐场的一个例子。

type ReqA = { type: 'a' }
type ReqB = { type: 'b' }

class GrpcClient {
    findA(request: ReqA) { };
    findB(request: ReqB) { };
}

class WrapperClient {
    rpc<GrpcClient, TMethod extends keyof GrpcClient>(client: GrpcClient, method: TMethod, req: any) {
    }
}

const grpcClient = new GrpcClient()
const client = new WrapperClient()

// This works

grpcClient.findA({ type: 'a' }) // correct
grpcClient.findB({ type: 'b' }) // correct

// This doesn't.
// It Matches the method name. That's good.
// But it does not check the request type.

client.rpc(grpcClient, 'findA', 1) // should fail
client.rpc(grpcClient, 'findB', 1) // should fail
client.rpc(grpcClient, 'findC', 1) // double fail, the method check works though

我可以使用泛型表达式的extends keyof对方法名称进行类型检查。 我无法输入检查请求参数。

我可以将联合硬编码为请求参数类型。

    rpc<GrpcClient, TMethod extends keyof GrpcClient>(client: GrpcClient, method: TMethod, req: ReqA | ReqB) {

gRPC绑定是动态生成的,我不想维护一个在重新生成绑定时可能会更改的可能请求类型的列表。

思考?

您可以使用条件类型来确定请求类型:

type ReqA = { type: 'a' }
type ReqB = { type: 'b' }

class PeopleServiceClient {
    findA(request: ReqA) { };
    findB(request: ReqB) { };
}

class WrapperClient {
    rpc<PeopleServiceClient, TMethod extends keyof PeopleServiceClient>(
        client: PeopleServiceClient, method: TMethod,
        req: PeopleServiceClient[TMethod] extends (arg: infer T) => void ? T : never) {
    }
}

const grpcClient = new PeopleServiceClient()
const client = new WrapperClient()

grpcClient.findA({ type: 'a' }) // correct
grpcClient.findB({ type: 'b' }) // correct

client.rpc(grpcClient, 'findA', {type: 'a'}) // correct
client.rpc(grpcClient, 'findA', {type: 'b'}) // fails
client.rpc(grpcClient, 'findA', 1) // fails
client.rpc(grpcClient, 'findB', 1) // fails
client.rpc(grpcClient, 'findC', 1) // fails

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM