Is it possible to link two fields of an interface together? I have the following interface:
export interface IContractKpi {
type: 'shipmentVolumes' | 'transitTime' | 'invoices';
visible: boolean;
content: IKpiContent;
}
export type IKpiContent =
| IKpiShipmentVolumeContent[]
| IKpiTransitTimeContent[]
| IKpiInvoicesContent;
My goal is for TypeScript to understand that:
When type
is 'shipmentVolumes'
, content
should be IKpiShipmentVolumeContent[]
.
When type
is 'transitTime'
, content
should be IKpiTransitTimeContent[]
.
When type
is 'invoices'
, content
should be IKpiInvoicesContent
.
The situation I am dealing with involves getting a response from the backend:
kpis: IContractKpi[]
I have a component that takes in kpi: IContractKpi
as props. This component dynamically renders different components based on the type using a lookup table:
const lookup: Record<'shipmentVolumes' | 'transitTime' | 'invoices', VueComponent> = {
shipmentVolumes: KpiShipmentVolumes,
transitTime: KpiTransitTime,
invoices: KpiInvoices,
}
const kpiComponent = computed(() => lookup[kpi.type])
<template>
<component :is="kpiComponent" :content="kpi.content" /> <--- I hope TypeScript isn't angry with me here :D
</template>
I can make the code simpler, but that is not the ideal solution.
<template>
<KpiShipmentVolumes v-if="kpi.type === 'shipmentVolumes'" :content="kpi.content" /> <--- this approach still causes issues
<KpiTransitTime v-if="kpi.type === 'transitTime'" :content="kpi.content" />
<KpiInvoices v-if="kpi.type === 'invoices'" :content="kpi.content" />
</template>