为不同的枚举定义特定的对象负载



假设我有这个代码——我知道它是错误的。

enum SocketClient {
PLAYER_LOGIN = "player:login",
PLAYER_LOGOUT = "player:logout",
}
enum SocketClientPayload {
PLAYER_LOGIN = { user: string; pass: string};
PLAYER_LOGOUT  =  { uuid: string;}
} 

type wsMessage = {
event: typeof SocketClient;
payload: SocketClientPayload[SocketClient];
};

我希望底部的payload与我为传入的SocketEvent指定的任何内容绑定,以便键入每个SocketEventpayload。有没有一种方法可以实现动态表单类型?

您可以为此使用映射类型。例如:

enum SocketClient {
PLAYER_LOGIN = "player:login",
PLAYER_LOGOUT = "player:logout",
}
type SocketClientPayload = {
[SocketClient.PLAYER_LOGIN]: { user: string; pass: string; };
[SocketClient.PLAYER_LOGOUT]: { uuid: string; };
};
type wsMessage<T extends SocketClient> = {
event: T;
payload: SocketClientPayload[T];
};
let test: wsMessage<SocketClient.PLAYER_LOGOUT> = {
event: SocketClient.PLAYER_LOGOUT,
payload: { uuid: 'test' }
};

TypeScript游乐场

通过使wsMessage类型通用,您可以让它根据SocketClient枚举的哪个成员来实例化它,从而确定要使用哪个有效负载类型

请注意,TypeScript在这样使用时不会推断泛型类型,这就是为什么我必须指定我创建的test变量的类型为SocketClient.PLAYER_LOGOUT,尽管理论上可以根据event属性的值来确定。但是TypeScript在泛型函数中使用时可以推断出这一点。例如:

function processPayload<T extends SocketClient>(message: wsMessage<T>) {
// Do something
}
// TypeScript can see the argument is of type `wsMessage<SocketClient.PLAYER_LOGIN>` based on its `event` property, and it infers the generic type of the function from that.
processPayload(
{
event: SocketClient.PLAYER_LOGIN,
payload: { user: 'test', pass: 'test' },
},
);

TypeScript游乐场

最新更新