TypeScript中的命令和响应泛型



我正在努力想出一个好的命令结构->响应通用。

我的目标是让一个函数从基于类型或接口的命令列表中接受命令,并使用该接口推断响应类型。

到目前为止,我已经成功地根据type属性正确地推断出预期的data,但我似乎无法推断出泛型的返回类型。

任何类似的例子的指针是非常欢迎的!我没能找到很多

代码示例:打印稿操场

type MappedData<E, T extends keyof E> = E[T];
type MappedType<E> = {
[K in keyof E]: {
type: K;
data: MappedData<E, K>;
};
}[keyof E];
interface ServerCommandInterface<T> {
_res?: T;
}
interface TestCommandA extends ServerCommandInterface<{responseA: boolean}> {
param_a: string;
}
interface TestCommandB extends ServerCommandInterface<{responseB: boolean}> {
param_b: string;
}
interface Commands {
command_a: TestCommandA;
command_b: TestCommandB;
}
function execute<C extends MappedType<Commands>>(command: C): typeof command.data._res {
// Logic (HTTP call or similar) that would result in _res type
return null as any;
}
const result = execute({
type: 'command_a',
data: {
param_a: 'param',
}
});
console.log(result.responseA); // I expect this to be a boolean

所以我认为你正在寻找的是像下面的帮助类型:

interface Commands {
command_a: {
param: { param_a: string },
response: { responseA: boolean }
},
command_b: {
param: { param_b: string },
response: { responseB: boolean }
}
}

这里Commands的每个属性都有一个键对应于传递给execute()的值的type属性。该值是一个对象类型,具有两个属性:paramresponseparam属性对应于传递给execute()的值的data属性,response属性对应于从execute()返回的值。请注意,paramresponse的名称完全是任意的,我们可以随意命名它们。这里不会涉及任何类型为Commands的值;它只是一个助手类型,允许我们以一种简单的方式表达execute()的呼叫签名:

function execute<K extends keyof Commands>(
command: { type: K, data: Commands[K]['param'] }
): Commands[K]['response'] {
return null as any;
}

因此,execute()函数在类型参数K中是泛型的,约束为Commands的一个键。那么,参数execute()type属性类型为K,data属性类型为Commands[K]['param']。(我们使用索引访问类型来获取CommandsK键控属性的类型,然后获得"param"键控属性)。返回类型为Commands[K]['response']

让我们看看它是否有效:

const result = execute({
type: 'command_a',
data: {
param_a: 'param',
}
});

这里编译器推断"command_a"K,因此调用签名被指定为

/* function execute<"command_a">(command: {
type: "command_a";
data: {
param_a: string;
};
}): {
responseA: boolean;
} */
因此result的类型为
/* const result: {
responseA: boolean;
} */

按预期:

result.responseA === true // okay

Playground链接到代码

相关内容

  • 没有找到相关文章

最新更新