【发布时间】: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