typescript - Ayrımcı olarak enum kullanılan ayrımcı birleşimi nasıl kullanılır
Bir diskriminatörün bir enum olduğu ve enum alanının değerinin başka bir alanın tanımsız olup olmadığını belirlediği bir ayrılmış birleşimim var. Şöyle ki:
enum Status {
TOP, BOTTOM, MIDDLE
}
type StatusReport =
| {
status: Status.TOP | Status.BOTTOM
message: undefined
}
| {
status: Status.MIDDLE
message: string
}
Her şey yolunda. Şimdi uygun parametrelerden bu türü oluşturacak bir fonksiyon tanıtıyorum:
function statusReporter(theStatus: Status, statusMessage:string):StatusReport{
return {
status: theStatus,
message: theStatus === Status.MIDDLE ? statusMessage : undefined
}
}
Bu fonksiyon mantığı bana sağlam görünüyor. status'ta ayarlanan enum değerine bağlı olarak message'e doğru değeri atayacak. Ama TS, Status'ın type Status.MIDDLE türüne atanamayacağını belirten hatalar veriyor. Bu tabii ki doğru, ama bence koşulum bunun olmasını engelliyor.
Neden bu hatayı alıyorum ve çözümü nedir?
İşte oyun alanı
theStatus'in türünü theStatus'in Status.MIDDLE'yi genişletip genişletmediğine bağlı olarak bir koşullu tür olarak belirtmeyi denedim (status: theStatus as typeof theStatus extends Status.MIDDLE ? Status.MIDDLE : Status), ama faydası olmadı. Aynı hatayı alıyorum.
Cevap #1
Nesnenizi oluşturmadan önce türü belirlemeniz gerekir.
function statusReporter(theStatus: Status, statusMessage:string):StatusReport{
return theStatus === Status.MIDDLE ? {
status: theStatus,
message: statusMessage
} : {
status: theStatus,
message: undefined
}
}
Oyun alanı linki
Cevap #2
Fonksiyon aşırı yüklemesini kullanmanız gerekiyor:
enum Status {
TOP, BOTTOM, MIDDLE
}
type WithoutMessage = {
status: Status.TOP | Status.BOTTOM
message: undefined
}
type WithMessage = {
status: Status.MIDDLE
message: string
}
type StatusReport = WithMessage | WithoutMessage
function statusReporter(theStatus: Status.MIDDLE, statusMessage: string): WithMessage
function statusReporter(theStatus: Exclude<Status, Status.MIDDLE>, statusMessage: string): WithoutMessage
function statusReporter(theStatus: Status, statusMessage: string): StatusReport
function statusReporter(theStatus: Status, statusMessage: string) {
return {
status: theStatus,
message: theStatus === Status.MIDDLE ? statusMessage : undefined
}
}
function builder(myStatus: Status) {
return statusReporter(myStatus, "hello");
};
const hof = builder(Status.MIDDLE) // StatusReport
const result = statusReporter(Status.MIDDLE, 'hello') // WithMessage
const result2 = statusReporter(Status.BOTTOM, 'hello') // WithoutMessage
const result3 = statusReporter(Status.TOP, 'hello') // WithoutMessage
Oyun alanı
Bu hatayı alıyorsunuz çünkü message özelliği string | undefined olarak değerlendiriliyor, oysa StatusReportundefined ya da message bekliyor, ama ikisini birden değil, yani birleşimi değil
GÜNCELLEME
function statusReporter(theStatus: Status, statusMessage: string): StatusReport {
if (theStatus === Status.MIDDLE) {
return {
status: theStatus,
message: statusMessage
}
}
return {
status: theStatus,
message: undefined
}
}
