javascript - 提供投影对象时键入 mongoose findOne 查询
问题描述
首先,这是一个打字稿唯一的问题。我不关心js部分。
我的最终目标是使用投影对象键入一个简单的猫鼬查找。
假设电影为 3 个字段:
- 名称 -> 字符串,
- 电子邮件 -> 字符串
- isGood -> 布尔值
Movie.findOne({ year: { $gte: 1980, $lte: 1989 }, {isGood: -1}, function(err, movie) {
// Here I want ts compiler to understand that returned object does not have the isGood property
});
我希望我返回的对象是这样输入的(没有 isGood 属性,因为我们在投影对象中省略了它。
{
name: string,
email: string
}
现在我有这个代码:
type Diff<T, U> = T extends U ? never : T; // Remove types from T that are assignable to U
interface Test {
blob: number;
pop: number;
}
interface UserProfile {
id: string
email: string
image: string | null
isAdmin: boolean
username: string
reviews: string[],
test: Test
}
type ExcludedTypes<T, U> = {
[K in Exclude<keyof T, keyof U>]: T[K]
}
type PartialFrom<T> = {
[P in keyof T]?: number | PartialFrom<T[P]>;
}
const excludeFn = <K extends Record<string, any>, T extends PartialFrom<K>>(user: K, projection: T): ExcludedTypes<K, T> => {
const newUser: K = {
...user
};
Object.keys(projection).forEach((key) => {
delete newUser[key];
})
return user;
}
const full: UserProfile = {
id: "reareaz",
email: "rezrza",
image: null,
isAdmin: false,
username: "rezaraz",
reviews: ["test"],
test: {
blob: 1221,
pop: 122,
}
}
const projection = {
email: -1,
image: -1,
reviews: -1,
}
const filteredObject = excludeFn(full, projection);
interface PartialUserProfile {
id: string
isAdmin: boolean
username: string
}
// this is just used to test that filteredObject is properly typed
const ppp = (a: PartialUserProfile): void => { }
// it should fail because email is not in filtered object anymore
ppp(filteredObject);
所以这里的目标是创建一个类型函数,它将完整对象作为第一个参数,一个部分对象并返回不在部分对象中的完整对象的字段。
我上面的例子只适用于一级属性:
这行得通 :
const full = {
image: 'string',
isFalse: true
}
const projection = {
image: -1
}
// will not have image property
const filteredObject = excludeFn(full, projection);
不会工作:
const full = {
image: 'string',
pasta: {
isGood: true,
brand: 'mypastabrand'
}
}
const projection = {
pasta: {
isGood: -1
}
}
const filteredObject = excludeFn(full, projection);
这不起作用,因为我的类型:
type ExcludedTypes<T, U> = {
[K in Exclude<keyof T, keyof U>]: T[K]
}
不超过一层深度,这就是我被困的地方