Pick 类型上不存在属性“_id”
Posted
技术标签:
【中文标题】Pick 类型上不存在属性“_id”【英文标题】:Property '_id' does not exist on type Pick 【发布时间】:2021-01-11 20:39:15 【问题描述】:我正在使用 Next.js,我正在尝试使用 TypeScript 和 mongoose 查询 MongoDB,但我遇到了类型错误。
types.d.ts
type dbPost =
_id: string
user:
uid: string
name: string
avatar: string
post:
title: string
description: string
markdown: string
slug: string
createdAt: string
export const getSlugData = async (slug: string) =>
await dbConnect()
const data:
| Pick<dbPost, '_id' | 'post' | 'user'>
// The problem seems to be here with Pick[]
| Pick<dbPost, '_id' | 'post' | 'user'>[]
| null = await Post.findOne( 'post.slug': slug ).lean().select('-__v')
const post =
...data,
_id: `$data._id`,
// _id and createdAt are objects created by mongoose which can't be serialized.
// They must be converted to a string
post:
...data.post,
createdAt: `$data.post.createdAt`,
,
return post
我收到以下错误:
Property '_id' does not exist on type 'Pick<dbPost, "_id" | "post" | "user"> | Pick<dbPost, "_id" | "post" | "user">[]'.
Property '_id' does not exist on type 'Pick<dbPost, "_id" | "post" | "user">[]'.ts(2339)
Pick<>[]
我做错了什么?
package.json
"dependencies":
"mongoose": "^5.10.6",
...
,
"devDependencies":
"@types/mongoose": "^5.7.36",
...
dbConnect() 是我从 Next.js 示例中获取的函数
【问题讨论】:
【参考方案1】:这是因为您告诉编译器 data
可能是一个数组,在这种情况下需要对单个对象进行不同的访问。
findOne
不返回数组,findOne
只返回 Record<string, T>
或 null
。您应该从类型联合中删除 Pick<dbPost, '_id' | 'post' | 'user'>[]
。
const data:
| Pick<dbPost, '_id' | 'post' | 'user'>
| null = await Post.findOne( 'post.slug': slug ).lean().select('-__v')
现在data
仍可能是null
,因此您只需确保您没有访问null
上的属性。整体功能:
export const getSlugData = async (slug: string) =>
await dbConnect()
const data:
| Pick<dbPost, '_id' | 'post' | 'user'>
| null = await Post.findOne( 'post.slug': slug ).lean().select('-__v')
// first check if data is null
const post = data &&
...data,
_id: `$data._id`,
// _id and createdAt are objects created by mongoose which can't be serialized.
// They must be converted to a string
post:
...data.post,
createdAt: `$data.post.createdAt`,
,
return post
为确保类型正确,还要确保您的 select
与您的 Pick<>
中的字段匹配。
【讨论】:
正确,但是当我使用您的解决方案时,编译器仍然抱怨类型联合:Type 'Pick<any, string | number | symbol> | Pick<any, string | number | symbol>[]' is not assignable to type 'Pick<dbPost, "_id" | "post" | "user">' Type 'Pick<any, string | number | symbol>[]' is missing the following properties from type 'Pick<dbPost, "_id" | "post" | "user">': _id, post, userts(2322)
@Diego,也许那是因为您还需要添加 .exec()
才能实际执行查询:await Post.findOne( 'post.slug': slug ).lean().select('-__v').exec()
我试过了。它没有改变错误。我现在将此函数移至 .js 文件。我不太了解,但是猫鼬的类型声明可能存在问题。我稍后会回到这个。谢谢。以上是关于Pick 类型上不存在属性“_id”的主要内容,如果未能解决你的问题,请参考以下文章