I am working with a normalized data inside redux store (all complex types are just ids referring to real object) and I would like to create a denormalized types using typescript's conditional mapped types feature.
I keep the actual type of the object the id is referring to as it's generic argument and from this I was able to create denormalized type correctly if only non array id attributes are used.
type Id<T extends HandlerBase<any>> = string & { __type: T };
class HandlerBase<T extends HandlerBase<T>> {};
class HandlerA extends HandlerBase<HandlerA> {
str: string;
b: Id<HandlerB>;
bArr: Id<HandlerB>[];
};
class HandlerB extends HandlerBase<HandlerA> {};
type DenormalizedHandler<T> = {
[P in keyof T]: T[P] extends Id<infer U> ? DenormalizedHandler<U> : T[P];
}
const handler: DenormalizedHandler<HandlerA> = undefined;
handler.str; // Is string
handler.b; // Is DenormalizedHandler<HandlerB>
handler.bArr; // Should be DenormalizedHandler<HandlerB>[]
Now I need to figure out how to possibly add second condition to DenormalizedHandler so it can correctly map Id<U> to DenormalizedHandler<U> and Id<U>[] to DenormalizedHandler<U>[].