Pesquisei de várias maneiras, mas não consegui encontrar mais informações sobre tipagem condicional. Estou tentando criar um tipo chamado ChatItemMessage
e ele tem 2 índices, type
e value
.
Este é o código atual:
type ChatItemMessage = {
type: ChatItemMessageType;
value: ChatMessage | ChatDate;
};
enum ChatItemMessageType {
Date = "date",
Message = "message",
}
type ChatMessage = {
id: number;
};
type ChatDate = {
date: string;
};
O que estou tentando fazer é definir condicionalmente o tipo value
com base no valor de type
:
export type ChatItemMessage = {
type: ChatItemMessageType;
value: (ChatItemMessage['type'] extends ChatItemMessageType.Message ? ChatMessage : ChatDate);
};
Isso não está funcionando, eu também tentei (e outras variações):
export type ChatItemMessage<T extends ChatItemMessageType> = {
type: T;
value: (T extends ChatItemMessageType.Message ? ChatMessage : ChatDate);
};
No meu código estou fazendo então:
declare const data: ChatItemMessage[]
data.map(
message => message.type === ChatItemMessageType.Date ?
message.value.date : // error!
// ~~~~ <-- Property 'date' does not exist on type 'ChatMessage'.
message.value.id.toFixed() // error!
// ~~ <-- Property 'id' does not exist on type 'ChatDate'.
);
O que eu quero é que message.value
seja ChatMessage
porque já verifiquei se é message.type === ChatItemMessageType.Message
, mas o IDE está sempre dizendo que é ChatDate
.
A ideia é que o IDE e qualquer desenvolvedor saibam que if type = ChatItemMessageType.Message
then value = ChatMessage
, else (nesse caso) será ChatDate
, então novos erros devem aparecer se o desenvolvedor tiver o tipo errado em mente no tempo de execução.
Nem tenho certeza se isso pode ser alcançado ou não. Se precisar de mais informações, me avise!