網站搜尋

TypeScript 在條件型別中推斷的泛型型別為未知


我無法理解為什麼在傳給 createRoute 的參數中,data 屬性沒有正確推斷為 FeatureFlagData。我基本上想實現的是根據 canActivate 陣列中的項目(因為它實現了泛型 GuardWithData)來推斷 createRoute 參數中 data 的類型。我這裡漏掉了什麼?另外,有沒有更好的方法達成相同的效果?

這裡有一些範例程式碼:

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
})

答案#1

interface Guard {
    canActivate: () => boolean
}

這意味著一個具有 canActivate 屬性的對象,該屬性是一個布林函數。你將 FeatureFlagGuard 傳入 createRoute 的方式,看起來你希望 FeatureFlagGuard 本身就是布林函數,而不是具有 canActivate 屬性的對象。

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: {}
})