Typescript 推断的泛型类型在条件类型中是未知的
Posted
技术标签:
【中文标题】Typescript 推断的泛型类型在条件类型中是未知的【英文标题】:Typescript inferred generic type is unknown in conditional type 【发布时间】:2020-09-22 15:01:46 【问题描述】:我无法理解为什么data
属性在createRoute
的参数中没有正确推断为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
)
【问题讨论】:
我没有遵循您为什么期望data
被推断为FeatureFlagData
类型的逻辑。你能解释一下你为什么会这样吗?
我希望当我调用createRoute
时,Typescript 能够推断出ExtractGuardData
中的U
,进而也推断出GuardWithData
中的泛型类型,我以后可以用于创建组合类型(或交集类型)Route & data: U
(ExtractGuardData
),其中类型U
被推断为与GuardWithData
(又名FeatureFlagData
)中的D
相同。我怀疑我在这里做了一些根本错误的事情(或者至少有错误的期望),但我无法弄清楚我正在寻找什么或如何获得我正在寻找的行为。
【参考方案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:
)
【讨论】:
对,我可能不太清楚Route
中的canActivate
只是一个命名约定,恰好与Guard
接口中的require 方法canActivate
同名。
我必须遵守Guard
接口,但仍然可以通过让我的Guard
扩展给定的@987654336 来指定createRoute
参数中data
属性的类型@。所以底层框架(在这种情况下是Angular)期望createRoute
中的canActivate
属性是Guard
类型(在我最初的问题中定义)。因此,我可以控制/修改的唯一部分是 GuardWithData
、FeatureFlagGuard
、ExtractGuardData
和 FeatureFlagData
,这有意义吗?以上是关于Typescript 推断的泛型类型在条件类型中是未知的的主要内容,如果未能解决你的问题,请参考以下文章