Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeScript Type Inference Error with AWS Amplify Data Schema in Monorepo Environment #2564

Open
rnrnstar2 opened this issue May 16, 2024 · 8 comments

Comments

@rnrnstar2
Copy link

Environment information

System:
  OS: macOS 14.0
  CPU: (10) arm64 Apple M2 Pro
  Memory: 202.08 MB / 16.00 GB
  Shell: /bin/zsh
Binaries:
  Node: 20.5.0 - /usr/local/bin/node
  Yarn: 1.22.19 - /usr/local/bin/yarn
  npm: 9.8.0 - /usr/local/bin/npm
  pnpm: 8.15.5 - ~/Library/pnpm/pnpm
NPM Packages:
  @aws-amplify/backend: 1.0.2
  @aws-amplify/backend-cli: 1.0.3
  aws-amplify: 6.3.2
  aws-cdk: 2.142.0
  aws-cdk-lib: 2.142.0
  typescript: 5.4.5
AWS environment variables:
  AWS_DEFAULT_PROFILE = cloudteam
  AWS_STS_REGIONAL_ENDPOINTS = regional
  AWS_NODEJS_CONNECTION_REUSE_ENABLED = 1
  AWS_SDK_LOAD_CONFIG = 1

Description

I'm encountering a TypeScript type inference error when using AWS Amplify's data schema in a monorepo environment. The node_modules directory is present only at the root level of the monorepo.

.
├── README.md
├── apps
│   └── admin
│       ├── README.md
│       ├── amplify.yml
│       ├── app
│       ├── next-env.d.ts
│       ├── next.config.js
│       ├── package.json
│       ├── postcss.config.js
│       ├── public
│       ├── tailwind.config.ts
│       └── tsconfig.json
├── package-lock.json
├── package.json
├── packages
│   ├── eslint-config
│   │   ├── README.md
│   │   ├── library.js
│   │   ├── next.js
│   │   ├── package.json
│   │   └── react-internal.js
│   ├── shared-backend
│   │   ├── amplify
│   │   ├── amplify.yml
│   │   ├── amplify_outputs.json
│   │   ├── hooks
│   │   ├── index.html
│   │   ├── package.json
│   │   ├── provider
│   │   ├── tsconfig.json
│   │   └── tsconfig.lint.json
│   ├── tailwind-config
│   │   ├── package.json
│   │   ├── tailwind.config.ts
│   │   └── tsconfig.json
│   ├── typescript-config
│   │   ├── base.json
│   │   ├── nextjs.json
│   │   ├── package.json
│   │   └── react-library.json
│   └── ui
│       ├── components
│       ├── dist
│       ├── package.json
│       ├── postcss.config.js
│       ├── styles.css
│       ├── tailwind.config.ts
│       ├── tsconfig.json
│       └── tsconfig.lint.json
├── test.json
├── tsconfig.json
└── turbo.json
import { generateClient } from "aws-amplify/data";
import { type Schema } from "../amplify/data/resource";
type Team = Schema["Team"];

const client = generateClient<Schema>();

await client.models.Team.create({
  id: "testid",
  name: "test",
});
(property) name: string
Type 'string' is not assignable to type '{ [x: number]: string; toString: () => string; charAt: (pos: number) => string; charCodeAt: (index: number) => number; concat: (...args: (string | ConcatArray<string>)[]) => string[]; ... 71 more ...; id?: string; }'.ts(2322)
util.d.ts(15, 130): The expected type comes from property 'name' which is declared here on type '{ [x: string]: { [x: number]: string; toString: () => string; charAt: (pos: number) => string; charCodeAt: (index: number) => number; concat: (...args: (string | ConcatArray<string>)[]) => string[]; ... 71 more ...; readonly [Symbol.unscopables]: { ...; }; }; [x: number]: { ...; }; id?: string; }'

Steps to Reproduce:

  1. Set up a monorepo environment with a single node_modules directory at the root.
  2. Use AWS Amplify Data Schema to create a model.
  3. Attempt to create a model instance with a type that includes a string property.

Expected Behavior:
The type inference should correctly recognize the string type for the name property without any errors.

Current Behavior:
TypeScript throws an error, indicating that the string type is not assignable to the expected type, which includes various methods and properties.

Environment:
Turborepo

スクリーンショット 2024-05-17 1 38 31

スクリーンショット 2024-05-17 1 38 59

@edwardfoyle edwardfoyle transferred this issue from aws-amplify/amplify-backend May 16, 2024
@chrisbonifacio
Copy link
Member

Hi @rnrnstar2, this seems similar to an issue we are currently aware of and working on a fix for. Can you share your schema to reproduce locally so we can confirm?

@rnrnstar2
Copy link
Author

import { type ClientSchema, a, defineData } from "@aws-amplify/backend";
import { oripaPostConfirmation } from "../functions/OripaPostConfirmation/resource";

const schema = a
  .schema({
    Team: a
      .model({
        name: a.string().required(),
        s3ImgKey: a.string(),
        shops: a.hasMany("Shop", "teamId"),
        teamMembers: a.hasMany("TeamMembers", "teamId"),
      })
      .authorization(allow => [allow.owner().to(['create', 'read', 'update']), allow.authenticated().to(["read", "update"])]),
    Shop: a
      .model({
        name: a.string().required(),
        s3ImgKey: a.string(),
        teamId: a.id(),
        team: a.belongsTo("Team", "teamId"),
        shopMembers: a.hasMany("ShopMembers", "shopId"),
      })
      .authorization(allow => [allow.owner().to(['create', 'read', 'update']), allow.authenticated().to(["read", "update"])]),
    Member: a
      .model({
        name: a.string().required(),
        s3ImgKey: a.string(),
        email: a.email().required(),
        teamMembers: a.hasMany("TeamMembers", "memberId"),
        shopMembers: a.hasMany("ShopMembers", "memberId"),
      })
      .secondaryIndexes((index) => [
        index("email").sortKeys(["name"]).queryField("listByEmail"),
      ])
      .authorization(allow => [allow.owner().to(['create', 'read', 'update']), allow.authenticated().to(["read"])]),
    TeamMembersType: a.enum(["OWNER", "MEMBER"]),
    TeamMembers: a
      .model({
        type: a.ref("TeamMembersType").required(),
        teamId: a.id().required(),
        memberId: a.id().required(),
        team: a.belongsTo("Team", "teamId"),
        member: a.belongsTo("Member", "memberId"),
      })
      .authorization(allow => [allow.owner().to(['create', 'read', 'update']), allow.authenticated().to(["read", "update", "create"])]),
    ShopMembersType: a.enum(["OWNER", "MEMBER"]),
    ShopMembers: a
      .model({
        type: a.ref("ShopMembersType").required(),
        shopId: a.id().required(),
        memberId: a.id().required(),
        shop: a.belongsTo("Shop", "shopId"),
        member: a.belongsTo("Member", "memberId"),
      })
      .authorization(allow => [allow.owner().to(['create', 'read', 'update']), allow.authenticated().to(["read", "update", "create"])]),
    OnePieceType: a.enum(["CHARACTER", "EVENT", "STAGE", "LEADER"]),
    OnePieceColor: a.enum([
      "RED",
      "BLUE",
      "GREEN",
      "YELLOW",
      "PURPLE",
      "BLACK",
    ]),
    OnePieceAttribute: a.enum([
      "STRIKE",
      "SLASH",
      "WISDOM",
      "RANGED",
      "SPECIAL",
    ]),
    OnePieceRarity: a.enum(["C", "UC", "R", "SR", "SEC", "P", "L", "SP"]),
    OnePieceItem: a
      .model({
        name: a.string().required(),
        s3ImgKey: a.string().required(),
        type: a.ref("OnePieceType").required(),
        colors: a.ref("OnePieceColor").array().required(),
        features: a.string().array().required(),
        attributes: a.ref("OnePieceAttribute").array(),
        rarity: a.ref("OnePieceRarity").required(),
        cost: a.integer(),
        power: a.integer(),
        counter: a.integer(),
        text: a.string(),
        getInfo: a.string(),
        colorKey: a.string(), // ソートキー用
        featureKey: a.string(), // ソートキー用
        attributeKey: a.string(), // ソートキー用
      })
      .secondaryIndexes((index) => [
        index("getInfo").sortKeys(["colorKey", "type"]).queryField("listByGetInfo"),
      ])
      .authorization(allow => [allow.owner().to(['create', 'read', 'update']), allow.authenticated().to(["read", "update", "create"])]),
  })
  .authorization(allow => [allow.resource(oripaPostConfirmation)]);

export type Schema = ClientSchema<typeof schema>;

export const data = defineData({
  schema,
  name: "OripaData",
  authorizationModes: {
    defaultAuthorizationMode: "userPool",
  },
});

this is data resource.ts.

@chrisbonifacio
Copy link
Member

@rnrnstar2 can you check your tsconfig and confirm that you have strict mode enabled? If it's enabled and you are still experiencing this issue, please let us know.

@waynet-ihm
Copy link

created a repo with this issue - still a blocker for me

https://github.com/waynet-ihm/amplify-issue

@chrisbonifacio
Copy link
Member

@waynet-ihm thank you! I was able to reproduce your error right away.

CleanShot 2024-07-11 at 14 49 42@2x

Although now I realize it's different from the one originally described here. Perhaps this deserves its own issue. If you create a new issue, I'll mark it a bug for the team to investigate further.

@chrisbonifacio
Copy link
Member

Hi @rnrnstar2 , just wanted to share an update on this: the team is aware of and working on a fix for these reference/type annotation errors

@chrisbonifacio chrisbonifacio added bug Something isn't working and removed pending-response labels Jul 15, 2024
@neerajvisal
Copy link

Hi @chrisbonifacio or @stocaaro any update on when this will be resolved? I am facing similar issue described here.

@iartemiev
Copy link
Member

iartemiev commented Oct 16, 2024

@neerajvisal - the issue should be resolved now. Please run npm update @aws-amplify/data-schema to patch the relevant package.

@waynet-ihm - I was able to successfully run npm run build in your repo after:

  1. updating @aws-amplify/data-schema to latest
  2. adding skipLibCheck: true to the top-level tsconfig in your repo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants