【问题标题】:How to infer generic in a curried function?如何在柯里化函数中推断泛型?
【发布时间】:2020-08-20 19:22:37
【问题描述】:

我正在尝试输入一个用于查询集合的 API。我希望它像这样使用:

interface Car {
  model: string
  doors: 2 | 4 | 5
  designers: string[]
}

const result = query({
  model: [ contains('tesla') ],
  doors: [ is(3) ],
  designers: [ includes('Franz') ],
  take: 5,
});

所以这是我不完美的方法:

type Query<Entity extends EntityType> = (config: QueryConfig<Entity>) => Promise<Entity[]>
type QueryConfig<Entity extends EntityType> =
  { [K in FilterScalarMembers<Entity>]?: ScalarBuilderFn<Entity[K]>[] }
  & { [K in FilterCollectionMembers<Entity>]?: CollectionBuilderFn<Entity[K]>[] }
  & { take: number };

type FilterCollectionMembers<Entity extends EntityType> =
  { [K in keyof Entity]: Entity[K] extends CollectionType ? K : never }[keyof Entity]

type FilterScalarMembers<Entity extends EntityType> =
  { [k in keyof Entity]: Entity[k] extends (string | number) ? k : never }[keyof Entity]

type ScalarBuilderFn<T extends string | number> = (builder: ScalarQueryBuilder<T>) => ScalarQueryBuilder<T>
type CollectionBuilderFn<T extends CollectionType> = (builder: CollectionQueryBuilder<T>) => CollectionQueryBuilder<T>
type ScalarQueryBuilder<T extends string | number> = {}
type CollectionQueryBuilder<T extends CollectionType> = {}
type EntityType = Record<string, any>
type CollectionType = ((string | number)[]) | Set<string | number>

const is = <T extends string | number>(arg: T): ScalarBuilderFn<T> => function() {} as unknown as ScalarBuilderFn<T>;

问题在这里变得很明显:doors: [ is(3) ] 因为类型没有缩小到2 | 4 | 5,TypeScript 不会给出关于3 参数的错误。我们可以对is 函数做些什么来帮助它正确推断类型吗?

【问题讨论】:

    标签: typescript typescript-generics


    【解决方案1】:

    您可以使用indexed types

    const result = query({
        doors: [is<Car['doors']>(3)]
    });
    

    您可以将is 传递给Car['doors'] 的通用参数,这将告诉is 它的参数必须可分配给Car['doors'],即2 | 4 | 5

    我不确定您是否需要所有这些类型 - 除非它们执行此处未显示的其他操作。你所需要的只是is 有一个泛型类型参数,它的参数需要匹配

    const is = <T>(val: T) => { } // rest of the implementation
    

    【讨论】:

    • 正如我所提到的,我希望从使用 is 的上下文中推断出 is 参数类型。手动指定泛型类型很容易出错。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-13
    • 2015-01-26
    • 2012-02-13
    • 2023-03-03
    • 2020-08-18
    • 2016-01-01
    • 1970-01-01
    相关资源
    最近更新 更多