Typescript 获取映射返回对象的类型。打字稿ts(2345)

Typescript 获取映射返回对象的类型。打字稿ts(2345),typescript,Typescript,我有一个使用any类型的代码,请检查注释//此处键入any: 我需要它,以便能够将数据推入该数组,因为您将能够在//行中的代码中执行下面的操作。//需要任何类型才能推入该数组 const ProjectList = () => { const [projects, setProjects] = useState<IFirebaseProject[]>(); useEffect(() => { let data:any[] = []; //HERE TYPE

我有一个使用
any
类型的代码,请检查注释
//此处键入any
: 我需要它,以便能够将数据推入该数组,因为您将能够在
//行中的代码中执行下面的操作。//需要任何类型才能推入该数组

const ProjectList = () => {
  const [projects, setProjects] = useState<IFirebaseProject[]>();
  useEffect(() => {
    let data:any[] = []; //HERE TYPE ANY
    firebase
      .firestore()
      .collection("projects")
      .onSnapshot((snapshot) => {
        let changes = snapshot.docChanges();
        changes.forEach(change => {console.log(change.doc.data())})
        const fbProjects = changes.map( (change) => ({
          id: change.doc.id,
          ...change.doc.data()
        }));
        fbProjects.forEach(fbProject => data.push(fbProject)) //NEED ANY TYPE TO PUSH INTO THE ARRAY
        setProjects([...data]);
      });
  }, []);
我知道通过
…change.doc.data()
获得的类型,但是如何强制执行我的类型,以便
fbProjects
满足我定义的确定类型

这是fbProjects的类型:

interface IFirebaseProject {
  id: string,
  authorFirstName: string,
  authorId: string,
  authorLastName: string
  content: string
  createdAt: Date
  title: string
}
所以它有id属性,我知道
…change.doc.data()
有其余的属性

如果我使用我的
IFirebaseProject
而不是
any
,我在数组中推送项目(
fbProjects.forEach(fbProject=>data.push(fbProject))
)时会得到一个错误,因为显然不符合类型

我得到的错误是:
类型为“{id:string;}”的参数不能分配给类型为“IFirebaseProject”的参数。类型“{id:string;}”缺少类型“IFirebaseProject”中的以下属性:authorFirstName、authorId、authorLastName、content和其他2个属性。ts(2345)

编辑: 控制台输出:


(使用
.forEach
记录的数据库中每个寄存器的一个对象)

我按如下方式拆分类型:

interface IFirebaseProject extends Destructured {
  id: string,
  
}

interface Destructured {
  authorFirstName: string,
  authorId: string,
  authorLastName: string
  content: string
  createdAt: Date
  title: string
}
然后我可以像这样设置分解部分的类型

const fbProjects = changes.map( (change) => ({
    id: change.doc.id,
    ...change.doc.data() as Destructured
}));

成功了。如果有更熟练的方法来解决这个问题,我很乐意知道。

您可以告诉TypeScript将从
map
返回的对象视为
IFirebaseProject

const fbProjects = changes.map((change) => ({
  id: change.doc.id,
  ...change.doc.data()
}) as IFirebaseProject);

console.log(change.doc.data())的输出是什么?我编辑了这个问题。请参见末尾,它是一个对象,除Id外,它具有
IFirebaseProject
接口的所有字段。然后在映射函数中,我使用
Id
属性组合该对象,以组合我需要的整个类型,并匹配接口类型nice!我就快到了,谢谢
const fbProjects = changes.map((change) => ({
  id: change.doc.id,
  ...change.doc.data()
}) as IFirebaseProject);