【问题标题】:Generics with typescript snapshots带有打字稿快照的泛型
【发布时间】:2020-10-02 00:39:58
【问题描述】:

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

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 属性吗?

【问题讨论】:

  • 也许强制转换是解决问题的错误方法,将doc.data() 强制转换为 T 至少没有错误。
  • 也与组合类型数据接口?这应该是错误的。 type 更适合这个,而不是接口;或者由接口和对象组成的类型。
  • ...疲劳。在我的示例中,它应该是类型而不是接口。我已经更新了这个问题。谢谢。

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


【解决方案1】:

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

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

  • 前者就像将snapshotAsArray 重命名为fooSnapshotAsArray 并在映射器中返回一个显式的FooType 值一样简单。
  • 后者有点“通用”。您通过要求 string id 对 snapshotAsArray 的 T 参数施加约束,然后使用显式返回类型提示编译器。
import * as fb from "firebase";

type FooType = {
    id: string;
    name: string;
    age: number;
    createdAt: fb.firestore.Timestamp;
};

function snapshotAsArray<T extends { id: string }>(
    snapshot: fb.firestore.QuerySnapshot
) {
    return snapshot.docs.map((doc) => <T>{ id: doc.id, ...doc.data() });
}

declare const admin: { firestore: () => fb.firestore.Firestore };

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

【讨论】:

    猜你喜欢
    • 2021-11-09
    • 1970-01-01
    • 2015-11-27
    • 1970-01-01
    • 1970-01-01
    • 2021-08-13
    • 2020-09-06
    • 2021-11-26
    • 2018-02-09
    相关资源
    最近更新 更多