最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to Eagerly Load Related Model Without TypeScript Error - Stack Overflow

programmeradmin7浏览0评论

I want to eagerly load a related aws-amplify gen 2 model and pass it on, but it seems to cause a typescript error no matter what I try. How do I do this without causing a typescript error? For background, I've done JavaScript, Python and dabbled in others but I'm new to TypeScript and Amplify. I'm using the web/ChatGPT to figure it out but neither seemed to help with this question.

The Error

Types of property 'dataType' are incompatible.
        Type '{ name: string; isComplex: boolean; dataCategories: LazyLoader<{ name: string; addDefault: boolean; dataEntries: LazyLoader<{ category: LazyLoader<... | null, false>; dataCategoryId: string; ... 7 more ...; readonly updatedAt: string; } | null, true>; ... 9 more ...; readonly updatedAt: string; } | null, true>; note...' is not assignable to type 'LazyLoader<{ name: string; isComplex: boolean; dataCategories: LazyLoader<{ name: string; addDefault: boolean; dataEntries: LazyLoader<{ category: LazyLoader<... | null, false>; dataCategoryId: string; ... 7 more ...; readonly updatedAt: string; } | null, true>; ... 9 more ...; readonly updatedAt: string; } | null, ...'.
          Type 'undefined' is not assignable to type 'LazyLoader<{ name: string; isComplex: boolean; dataCategories: LazyLoader<{ name: string; addDefault: boolean; dataEntries: LazyLoader<{ category: LazyLoader<... | null, false>; dataCategoryId: string; ... 7 more ...; readonly updatedAt: string; } | null, true>; ... 9 more ...; readonly updatedAt: string; } | null, ...'.

The Set Up

api.ts

/**
 * Subscribe to real-time updates for data categories, including their data types.
 * @param {Function} callback - Function to update state with new data.
 * @returns {Function} Unsubscribe function.
 */
export function subscribeToDataCategories(
  callback: (items: Schema["DataCategory"]["type"][]) => void
): () => void {
  const sub = client.models.DataCategory.observeQuery().subscribe({
    next: async (result: { items?: Schema["DataCategory"]["type"][] }) => {
      console.log("Updating DataCategories:", result.items);

      if (!result.items) {
        callback([]);
        return;
      }

      const enrichedItems = await Promise.all(
        result.items.map(async (item) => {
          try {
            let dataType: Schema["DataType"]["type"] | undefined;

            if (item.dataType && typeof item.dataType === "function") {
              // Resolve LazyLoader
              const resolved = await item.dataType();
              dataType = resolved?.data ?? undefined;
            }

            return { ...item, dataType };
          } catch (error) {
            console.error(
              `Failed to fetch DataType for ID ${item.dataTypeId}:`,
              error
            );
            return { ...item };
          }
        })
      );

      console.log("Enriched Categories:", enrichedItems);

      callback(enrichedItems);
    },
    error: (error: unknown) => {
      console.error("Subscription error:", error);
    },
  });

  return () => sub.unsubscribe(); // Cleanup function
}

resources.ts

Here is my resources.ts file

import { type ClientSchema, a, defineData } from "@aws-amplify/backend";
import { postConfirmation } from "../auth/post-confirmation/resource";

const schema = a
  .schema({
    UserProfile: a
      .model({
        email: a.string().required(),
        profileOwner: a.string(),
      })
      .secondaryIndexes((index) => [index("email")])
      .authorization((allow) => [
        allow.owner(),
        allow.ownerDefinedIn("profileOwner"),
        allow.groups(["Admins"]).to(["read"]),
      ]),
    DataType: a
      .model({
        name: a.string().required(),
        note: a.string(),
        isComplex: a.boolean().required(),
        dataCategories: a.hasMany("DataCategory", "dataTypeId"),
      })
      .secondaryIndexes((index) => [index("name")])
      .authorization((allow) => [allow.authenticated(), allow.publicApiKey()]),
    DataCategory: a
      .model({
        name: a.string().required(),
        note: a.string(),
        addDefault: a.boolean().required(),
        defaultValue: a.string(),
        options: a.string().array(), // For future use with options of values
        dataEntries: a.hasMany("DataEntry", "dataCategoryId"),
        dataTypeId: a.id().required(), // ✅ Explicitly define the reference field
        dataType: a.belongsTo("DataType", "dataTypeId"),
        entryCount: a.integer().default(0),
      })
      .secondaryIndexes((index) => [index("name")])
      .authorization((allow) => [
        allow.owner(),
        allow.groups(["Admins"]).to(["read"]),
        allow.publicApiKey(), // TODO: Remove. FOR TESTING
      ]),
    DataEntry: a
      .model({
        note: a.string(),
        category: a.belongsTo("DataCategory", "dataCategoryId"),
        dataCategoryId: a.id().required(),
        date: a.date().required(),
        value: a.string().required(),
        dummy: a.integer().default(0),
      })
      .secondaryIndexes((index) => [
        index("dataCategoryId")
          .name("categoryEntriesByDate")
          .queryField("listCategoryEntries")
          .sortKeys(["date"]),
        index("dummy")
          .name("entriesByDate")
          .queryField("listByDate")
          .sortKeys(["date"]),
      ])
      // client.models.DataEntry.listDataentryByDataCategoryId({dataCategoryId: "ID"})
      .authorization((allow) => [
        allow.owner(),
        allow.groups(["Admins"]).to(["read"]),
        allow.publicApiKey(), // TODO: Remove. FOR TESTING
      ]),
  })
  .authorization((allow) => [allow.resource(postConfirmation)]);

export type Schema = ClientSchema<typeof schema>;

// export const schema = schema;
export { schema };

export const data = defineData({
  schema,
  authorizationModes: {
    defaultAuthorizationMode: "userPool", // Changed from public api key. /react/build-a-backend/data/customize-authz/
    apiKeyAuthorizationMode: {
      expiresInDays: 30,
    },
  },
});

Attempts

Attempt 1

This time I tried partially custom types, still errored.

type ResolvedDataType = Omit<Schema["DataType"]["type"], "dataCategories"> & {
  dataCategories?: Schema["DataCategory"]["type"][];
};

type EnrichedDataCategory = Omit<Schema["DataCategory"]["type"], "dataType"> & {
  dataType?: ResolvedDataType;
};

export function subscribeToDataCategories(
  callback: (items: EnrichedDataCategory[]) => void
): () => void {

Attempt 2

Here I tried just adding DataType to the standard DataCategory type but it also errored.

export function subscribeToDataCategories(
  callback: (
    items: (Schema["DataCategory"]["type"] & {
      dataType?: Schema["DataType"]["type"];
    })[]
  ) => void
): () => void {
发布评论

评论列表(0)

  1. 暂无评论