【发布时间】:2023-02-06 06:18:47
【问题描述】:
我有一个受 Prisma 启发的函数,它从对象生成 SQL 查询字符串,然后发出 SQL 查询请求并返回检索到的对象。
这是代码的 typescript playground (original code, see new below) 最小复制。
我目前正在使用泛型来设置预期的输出,但它总是返回完整的对象,即使应用了 select 也是如此。
如果有的话,有没有办法返回根据提供的选择对象过滤的输出类型?我试过使用 keyof (typeof query)["select"] 但这会获取选择类型的键,而不是运行时提供的值。
更新:我在这方面取得了一些进展,我能够让 output2 和 output3 输出正确的类型,但仍然不是 output1。 这是一个带有更新代码的新typescript playground链接,我已经更新了帖子中的代码。
游乐场代码:
type ExpectedOutput = {
aField: string;
bField: number;
cField: string;
dField: number;
eField: string;
fField: number;
gField: string;
}
type ObjectOrTrue<Type> = Type extends Record<string, any>
? { [Property in keyof Type]: ObjectOrTrue<Property> }
: true;
async function myFunction<
Type extends Record<string, any> = Record<string, unknown>
>(query: {
select?: Partial<{ [Property in keyof Type]: ObjectOrTrue<Type[Property]> }>;
from: string;
where?: Partial<{ [Property in keyof Type]: Type[Property] }>;
order?: Partial<{ [Property in keyof Type]: "ASC" | "DESC" }>;
limit?: number;
offset?: number;
}) {
const {select} = query;
// Simulated output of function
if(select === undefined) {
console.log('select is undefined');
console.log({query});
return {} as Type;
}
return {} as {[Property in keyof typeof select]: Type[Property]};
}
async function runAllTests() {
const output1 = await myFunction<ExpectedOutput>({
select: {
aField: true,
bField: true,
cField: true,
},
from: 'SomeTable',
});
/*
output1 type === ExpectedOutput, but I would like it to be
{
aField: string,
bField: number,
cField: string,
}
*/
const output2 = await myFunction({
select: {
aField: true,
bField: true,
cField: true,
},
from: 'SomeTable',
});
/*
output2 type === {
aField: unknown,
bField: unknown,
cField: unknown,
}
which is what it should be.
*/
const output3 = await myFunction<ExpectedOutput>({
from: 'SomeTable',
});
/*
output3 type === ExpectedOutput which is what it should be.
*/
}
runAllTests();
【问题讨论】:
标签: typescript