具有打字稿快照的泛型

时间:2020-06-12 08:10:22

标签: typescript google-cloud-firestore typescript-generics

我有一个具有固定键和动态键的实体/接口。

type FooType = {
  id: string;
  name: string;
  age: number;
  createdAt: Timestamp;
} & {[id: string]: number; }

将这些数据从Cloud Firestore中拉出时,我想将其转换为包含文档ID的数组。

function snapshotAsArray<T>(snap): T[] {
  return snapshot
    .docs
    .map((doc): T => ({ id: doc.id, ...doc.data() }));
}

function getFoo(): Promise<FooType[]> {
  return admin.firestore()
    .collection('foo')
    .get()
    .then((snapshot) => snapshotAsArray<FooType>(snapshot));
}

我想使snapshotAsArray()通用/可重用,但出现以下错误。

Type '{ id: string; }' is not assignable to type 'T'.
'{ id: string; }' is assignable to the constraint of type 'T',
but 'T' could be instantiated with a different subtype of constraint '{}'.

我可以这样做,以便泛型T必须始终具有id属性吗?

1 个答案:

答案 0 :(得分:4)

您要的仿制药种类是impossible
您不能有一个其函数调用者指定类型T并返回类型T的值的函数,因为在运行时没有静态类型信息。

因此,您必须为snapshotAsArray提供专门的FooType(即,不是通用的),或者使用确切的类型提示编译器。

  • 前者就像将snapshotAsArray重命名为fooSnapshotAsArray并在映射器中返回明确的FooType值一样简单。
  • 后者有点“泛型”。通过要求snapshotAsArray的{​​{1}}参数具有一个T string来对其施加约束,然后用明确的返回类型提示编译器。
id