I can't wrap my head around why the data property isn't properly inferred to FeatureFlagData in the arguments to createRoute. Essentially what I am trying to achieve is infer the type of data in the createRoute argument, based on the item in canActivate array (as it implements the generic GuardWithData). What am I missing here? Also, is there a better way of achieving the same thing?
Here is some example code:
interface Guard {
canActivate: () => boolean
}
export interface GuardWithData<D> extends Guard {
data?: D;
}
export type DataType<T> = T extends GuardWithData<infer D> ? D : unknown;
class FeatureFlagGuard implements GuardWithData<FeatureFlagData> {
canActivate() { return true; };
}
interface Route {
canActivate: any,
data?: object
}
interface FeatureFlagData {
featureFlag: string;
}
type ExtractGuardData<A extends Route> = A extends {
canActivate: GuardWithData<infer U>,
}
? Route & { data: U }
: never;
function createRoute<U extends Route>(route: ExtractGuardData<U>) {
return route;
}
createRoute({
canActivate: FeatureFlagGuard,
data: {} // <-- This type is to unknown, rather than the expected FeatureFlagData
})