简体   繁体   中英

Typescript inferred generic type is unknown in conditional type

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
})
interface Guard {
    canActivate: () => boolean
}

This means an object with the property canActivate that is a boolean function. The way you're passing in FeatureFlagGuard to createRoute , it looks like you want FeatureFlagGuard to be the boolean function, not an object with the canActivate property.

interface Guard {
  (): boolean
}

export interface GuardWithData<D> extends Guard {
  (data?: D): boolean;
}

const FeatureFlagGuard: GuardWithData<FeatureFlagData> =
  (data?: FeatureFlagData) => true;

interface Route<D> {
  canActivate: GuardWithData<D>,
  data?: D
}

interface FeatureFlagData {
  featureFlag: string;
}

function createRoute<D>(route: Route<D>) {
  return route;
}

createRoute({
  canActivate: FeatureFlagGuard,
  data: {}
})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM