enum Letter {
A = "A",
B = "B",
C = "C"
}
export type EntityT<T extends Letter = Letter> = T extends Letter.A
? { a: number }
: T extends Letter.B
? { b: string }
: T extends Letter.C
? { c: string }
: never;
type DeltaT<T extends EntityT> = _DeltaT<T, keyof T>;
export type _DeltaT<E extends EntityT, K extends keyof E> = {
key: K;
oldValue: E[K];
newValue: E[K];
};
export type ProblemT<T extends Letter = Letter> = EntityT<T> extends infer E
? {
id: string;
type: T;
delta: DeltaT<E>[];
oldEntity: E;
newEntity: E;
}
: never;
const testCase: ProblemT<Letter.A> = {
id: "id",
type: Letter.A,
delta: [{ key: "a", oldValue: 1, newValue: 2 }],
oldEntity: { a: 1 },
newEntity: { a: 2 }
};
function myFunc<T extends Letter>(e: ProblemT<T>) {
switch (e.type) {
case Letter.A: {
const uselessConversion = e as ProblemT<Letter.A>;
return uselessConversion.newEntity.a;
}
case Letter.B: {
const uselessConversion = e as ProblemT<Letter.B>;
return uselessConversion.newEntity.b;
}
case Letter.C: {
const uselessConversion = e as ProblemT<Letter.C>;
return uselessConversion.newEntity.c;
}
}
}
I would like to define the type ProblemT
based on its type
property, returning different values in oldEntity
and newEntity
.
I aim to use the switch within myFunc
without manual conversion of objects, letting TypeScript infer the type based on the type
. However, this does not work as expected.
How can I make the switch automatically infer the type without the need for manual conversions?
Is there a more effective way to declare ProblemT
with different types so that inference works with the switch?
Here is a link to the TypeScript playground