I have some type definitions as shown below.
type PayloadType = 'A' | 'B';
interface Payload<T extends PayloadType> {
type: T;
}
interface PayloadA extends Payload<'A'> {
state: string
}
interface PayloadB extends Payload<'B'> {
serialNumber: string;
}
type TPayload = PayloadA | PayloadB;
type PayloadInterpretation<T extends TPayload> = {
payload: T;
entries: T[]; // This property is only for demonstration purpose
};
type TPayloadInterpretation = PayloadInterpretation<PayloadA> | PayloadInterpretation<PayloadB>;
function f(interpretation: TPayloadInterpretation) {
if (interpretation.payload.type === 'B') {
const payload = interpretation.payload; // payload is of type PayloadB
const entries = interpretation.entries; // entries is of type PayloadA[] | PayloadB[]
}
}
The comments show that even the type of payload can be correctly narrowed down to PayloadB based on discriminated unions, but the type T[] for entries is still PayloadA[] | PayloadB[].
I was thinking if typescript knows the type T for payload is PayloadA, it should also be able to narrow entries: T[] to entries: PayloadB[]. I know I could do a type casting like:
function f(interpretation: TPayloadInterpretation) {
if (interpretation.payload.type === 'B') {
const payloadBInterpretation = interpretation as PayloadInterpretation<PayloadB>;
...
}
}
But my question would be is there any other way to do this?
The code is here in typescript playground.
Thanks!