简体   繁体   English

Typescript 推断的泛型类型在条件类型中未知

[英]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 .我无法理解为什么data属性没有正确推断为FeatureFlagData中的 FeatureFlagData 到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 ).本质上,我想要实现的是根据canActivate数组中的项目(因为它实现了通用GuardWithData )来推断createRoute参数中的data类型。 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.这意味着具有 canActivate 属性的canActivate是 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.您将FeatureFlagGuard传递给createRoute的方式,看起来您希望FeatureFlagGuard成为 boolean function,而不是带有canActivate属性的 object。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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