Typescript 如何关联函数';s输入参数及其返回类型以利用autosuggest功能

Typescript 如何关联函数';s输入参数及其返回类型以利用autosuggest功能,typescript,typescript-generics,Typescript,Typescript Generics,我试图使用泛型将参数类型和函数的返回类型链接在一起。我已经找到了一个解决方案,但我发现它是次优的,因为我觉得它可以做得更好 基本上,我有以下功能: function postCommand<T extends AvailableCommands>( commandName: T, commandArguments: ArgumentType<T> ): Observable<PayloadType<T>> { return

我试图使用泛型将参数类型和函数的返回类型链接在一起。我已经找到了一个解决方案,但我发现它是次优的,因为我觉得它可以做得更好

基本上,我有以下功能:

function postCommand<T extends AvailableCommands>(
    commandName: T,
    commandArguments: ArgumentType<T>
): Observable<PayloadType<T>> {
    return httpClient.post<PayloadType<T>>(`/command/${commandName}`, commandArguments);
}
现在,这看起来更具可读性,并且具有相同的效果。我还有一些自我暗示。唯一的警告是:如果我从
CommandMap
接口中省略
createpost
,编译器不会介意。这是上述两种实现的问题

这正是我想要的,除了我提到的警告。所以,我现在的问题是:

有没有办法让编译器记住这样一个事实:我没有在
CommandMap
中为所有可用的
命令定义映射,并且仍然对参数和
postCommand
的返回类型进行自动建议

(我已经用我的最新版本创建了一个,以及一个模拟实现的
post
和我在项目中使用的TypeScript版本)

编辑: 对我来说,最好的答案就藏在眼前:

我现在基本上只使用一种类型

export interface CommandMap {
    [index: string]: { arguments: any; payload: any };
    'create-group': { arguments: CreateGroupArguments; payload: CreateGroupPayload };
    'create-post': { arguments: CreatePostArguments; payload: CreatePostPayload };
}
以及函数调用:

public postCommand<T extends keyof CommandMap>(
    commandName: T,
    commandArguments: CommandMap[T]['arguments']
): Observable<CommandMap[T]['payload']> {
    return this.httpClient.post<CommandMap[T]['payload']>(`/command/${commandName}`, commandArguments);
}
公共邮政编码(
命令名:T,
commandArguments:CommandMap[T]['arguments']
):可见{
返回此.httpClient.post(`/command/${commandName}`,commandArguments);
}
通用命令现在扩展了CommandMap的
keyof
。由于
CommandMap
已经包含了我的命令的所有定义,因此我不需要额外的
AvailableCommands
类型


所有的自动建议功能仍然可用,并且错误在正确的位置(接口定义本身,如果有的话)

如果您正在查找编译器错误,如果
CommandMap
的键与
AvailableCommands
不匹配,您可以在单独的一行中进行:

type VerifyCommandMap<
  // if the next line is an error, CommandMap has extra keys
  K extends AvailableCommands = keyof CommandMap,
  // if the next line is an error, CommandMap is missing some keys
  L extends keyof CommandMap = AvailableCommands 
  > = true;
输入VerifyCommandMap<
//如果下一行是错误的,CommandMap有额外的键
K extends AvailableCommands=keyof CommandMap,
//如果下一行是错误,则CommandMap缺少一些键
L扩展keyof CommandMap=AvailableCommands
>=正确;
基本上,您强制默认参数满足通用约束,而只有当
AvailableCommands
keyof CommandMap
相同时,默认参数才满足这些约束


这有帮助吗?

但是如果您注释掉
create post
则编译器会非常介意,因为函数上发生了错误。由于
CommandMap[T]
将无效,因为
T
不是正确的s键(或
CommandMap
的键子集),我没有注意到这一点。唯一的问题是错误本质上是不透明的。这是可行的,但我认为这对于以后查看代码的人来说并不清楚。所以,结合@jcalz的建议,我认为我可以得到错误和一些错误指示。这很有帮助,它仍然有点不透明和怪异,但它确实有效,我认为我可以接受。
public postCommand<T extends keyof CommandMap>(
    commandName: T,
    commandArguments: CommandMap[T]['arguments']
): Observable<CommandMap[T]['payload']> {
    return this.httpClient.post<CommandMap[T]['payload']>(`/command/${commandName}`, commandArguments);
}
type VerifyCommandMap<
  // if the next line is an error, CommandMap has extra keys
  K extends AvailableCommands = keyof CommandMap,
  // if the next line is an error, CommandMap is missing some keys
  L extends keyof CommandMap = AvailableCommands 
  > = true;