aws-amplify / amplify-js

A declarative JavaScript library for application development using cloud services.
https://docs.amplify.aws/lib/q/platform/js
Apache License 2.0
9.39k stars 2.11k forks source link

Type instantiation is excessively deep and possibly infinite. TS(2589) #12973

Open asp3 opened 4 months ago

asp3 commented 4 months ago

Before opening, please confirm:

JavaScript Framework

Next.js

Amplify APIs

GraphQL API

Amplify Version

v6

Amplify Categories

No response

Backend

Amplify CLI

Environment information

``` # Put output below this line System: OS: macOS 12.6.8 CPU: (8) x64 Intel(R) Core(TM) i7-4770HQ CPU @ 2.20GHz Memory: 3.59 GB / 16.00 GB Shell: 5.8.1 - /bin/zsh Binaries: Node: 20.10.0 - ~/.nvm/versions/node/v20.10.0/bin/node Yarn: 1.22.21 - ~/.nvm/versions/node/v20.10.0/bin/yarn npm: 10.2.3 - ~/.nvm/versions/node/v20.10.0/bin/npm pnpm: 7.13.2 - /usr/local/bin/pnpm Browsers: Chrome: 121.0.6167.139 Safari: 16.6 npmPackages: @ampproject/toolbox-optimizer: undefined () @aws-amplify/core: ^6.0.13 => 6.0.13 @aws-amplify/core/internals/adapter-core: undefined () @aws-amplify/core/internals/aws-client-utils: undefined () @aws-amplify/core/internals/aws-client-utils/composers: undefined () @aws-amplify/core/internals/aws-clients/cognitoIdentity: undefined () @aws-amplify/core/internals/aws-clients/pinpoint: undefined () @aws-amplify/core/internals/providers/pinpoint: undefined () @aws-amplify/core/internals/utils: undefined () @aws-amplify/core/server: undefined () @aws-amplify/ui-react: ^6.1.2 => 6.1.2 @aws-amplify/ui-react-internal: undefined () @babel/core: undefined () @babel/runtime: 7.22.5 @edge-runtime/cookies: 4.0.2 @edge-runtime/ponyfill: 2.4.1 @edge-runtime/primitives: 4.0.2 @emotion/react: ^11.11.3 => 11.11.3 @hapi/accept: undefined () @mswjs/interceptors: undefined () @napi-rs/triples: undefined () @next/font: undefined () @next/react-dev-overlay: undefined () @opentelemetry/api: undefined () @segment/ajv-human-errors: undefined () @types/node: ^20 => 20.11.16 @types/react: ^18 => 18.2.55 @types/react-dom: ^18 => 18.2.18 @vercel/nft: undefined () @vercel/og: 0.5.15 acorn: undefined () amphtml-validator: undefined () anser: undefined () arg: undefined () assert: undefined () async-retry: undefined () async-sema: undefined () autoprefixer: ^10.0.1 => 10.4.17 aws-amplify: ^6.0.13 => 6.0.13 aws-amplify/adapter-core: undefined () aws-amplify/analytics: undefined () aws-amplify/analytics/kinesis: undefined () aws-amplify/analytics/kinesis-firehose: undefined () aws-amplify/analytics/personalize: undefined () aws-amplify/analytics/pinpoint: undefined () aws-amplify/api: undefined () aws-amplify/api/server: undefined () aws-amplify/auth: undefined () aws-amplify/auth/cognito: undefined () aws-amplify/auth/cognito/server: undefined () aws-amplify/auth/enable-oauth-listener: undefined () aws-amplify/auth/server: undefined () aws-amplify/datastore: undefined () aws-amplify/in-app-messaging: undefined () aws-amplify/in-app-messaging/pinpoint: undefined () aws-amplify/push-notifications: undefined () aws-amplify/push-notifications/pinpoint: undefined () aws-amplify/storage: undefined () aws-amplify/storage/s3: undefined () aws-amplify/storage/s3/server: undefined () aws-amplify/storage/server: undefined () aws-amplify/utils: undefined () axios: ^1.6.5 => 1.6.7 babel-packages: undefined () browserify-zlib: undefined () browserslist: undefined () buffer: undefined () bytes: undefined () ci-info: undefined () cli-select: undefined () client-only: 0.0.1 comment-json: undefined () compression: undefined () conf: undefined () constants-browserify: undefined () content-disposition: undefined () content-type: undefined () cookie: undefined () cross-spawn: undefined () crypto-browserify: undefined () css.escape: undefined () data-uri-to-buffer: undefined () debug: undefined () devalue: undefined () domain-browser: undefined () edge-runtime: undefined () eslint: ^8 => 8.56.0 eslint-config-next: 14.0.4 => 14.0.4 events: undefined () find-cache-dir: undefined () find-up: undefined () fresh: undefined () get-orientation: undefined () glob: undefined () gzip-size: undefined () http-proxy: undefined () http-proxy-agent: undefined () https-browserify: undefined () https-proxy-agent: undefined () icss-utils: undefined () ignore-loader: undefined () image-size: undefined () is-animated: undefined () is-docker: undefined () is-wsl: undefined () jest-worker: undefined () json5: undefined () jsonwebtoken: undefined () loader-runner: undefined () loader-utils: undefined () lodash.curry: undefined () lru-cache: undefined () micromatch: undefined () mini-css-extract-plugin: undefined () nanoid: undefined () native-url: undefined () neo-async: undefined () next: 14.0.4 => 14.0.4 node-fetch: undefined () node-html-parser: undefined () ora: undefined () os-browserify: undefined () p-limit: undefined () path-browserify: undefined () platform: undefined () postcss: ^8 => 8.4.34 (8.4.31) postcss-flexbugs-fixes: undefined () postcss-modules-extract-imports: undefined () postcss-modules-local-by-default: undefined () postcss-modules-scope: undefined () postcss-modules-values: undefined () postcss-preset-env: undefined () postcss-safe-parser: undefined () postcss-scss: undefined () postcss-value-parser: undefined () process: undefined () punycode: undefined () querystring-es3: undefined () raw-body: undefined () react: ^18 => 18.2.0 react-builtin: undefined () react-dom: ^18 => 18.2.0 react-dom-builtin: undefined () react-dom-experimental-builtin: undefined () react-experimental-builtin: undefined () react-is: 18.2.0 react-refresh: 0.12.0 react-server-dom-turbopack-builtin: undefined () react-server-dom-turbopack-experimental-builtin: undefined () react-server-dom-webpack-builtin: undefined () react-server-dom-webpack-experimental-builtin: undefined () regenerator-runtime: 0.13.4 sass-loader: undefined () scheduler-builtin: undefined () scheduler-experimental-builtin: undefined () schema-utils: undefined () semver: undefined () send: undefined () server-only: 0.0.1 setimmediate: undefined () shell-quote: undefined () source-map: undefined () stacktrace-parser: undefined () stream-browserify: undefined () stream-http: undefined () string-hash: undefined () string_decoder: undefined () strip-ansi: undefined () superstruct: undefined () tailwindcss: ^3.3.0 => 3.4.1 tar: undefined () terser: undefined () text-table: undefined () timers-browserify: undefined () tty-browserify: undefined () typescript: ^5 => 5.3.3 ua-parser-js: undefined () unistore: undefined () util: undefined () vm-browserify: undefined () watchpack: undefined () web-vitals: undefined () webpack: undefined () webpack-sources: undefined () ws: undefined () zod: undefined () npmGlobalPackages: corepack: 0.22.0 npm: 10.2.3 yarn: 1.22.21 ```

Describe the bug

First off, I want to say thanks for setting up V6! This new version is a huge upgrade over V5, and we are loving every part of it! While on the path to start strongly typing everything we possibly could, we started running into the issue Type instantiation is excessively deep and possibly infinite. TS(2589) while trying to type our server client that is getting passed around. We have a bit of a unique setup, where we have shared code between our mobile and web apps, so when using server context, we pass the serverClient that is generated though generateServerClientUsingCookies into our shared code. To keep this strongly typed, we use the type from

import { V6ClientSSRCookies } from "@aws-amplify/api-graphql";

serverClient?: V6ClientSSRCookies;

which seems to lead to that error. when removing this type, the compiler works again. This should be a pretty easily reproducible bug under the conditions. we can of course add a @ts-ignore to each call, but just wondering if there was some easier way to clean this up!

Expected behavior

Be able to use the types provided in api-graphql (import { V6ClientSSRCookies } from "@aws-amplify/api-graphql") without having typescript errors.

Reproduction steps

  1. use type V6ClientSSRCookies somewhere
  2. call that function by passing in a generated client, either through generateServerClientUsingCookies or generateClient

Code Snippet

No response

Log output

No response

aws-exports.js

No response

Manual configuration

No response

Additional configuration

No response

Mobile Device

No response

Mobile Operating System

No response

Mobile Browser

No response

Mobile Browser Version

No response

Additional information and screenshots

No response

asp3 commented 4 months ago
export const serverClient = generateServerClientUsingCookies({
    config: awsConfig,
    cookies,
}) as V6ClientSSRCookies;

fixed for me with a simple addition of the type here. not sure if it really changes anything

svidgen commented 4 months ago

I've attempted to repro this to no avail. Are you seeing this at build time, or only in the IDE?

asp3 commented 4 months ago

@svidgen This is just at an IDE level, doesn't really cause any build issues. To fix the red underlines, I just explicitly set the types to V6ClientSSRCookies at every level, and the errors seem to go away.

export const serverClient = generateServerClientUsingCookies({
    config: awsConfig,
    cookies,
}) <<< as V6ClientSSRCookies >>> (adding this)

or

export const serverClient:  <<< as V6ClientSSRCookies >>> (adding this) = generateServerClientUsingCookies({
    config: awsConfig,
    cookies,
})
svidgen commented 4 months ago

Are you using VS Code? If so, can you confirm VS Code is configured (or has recognized) the correct version of typescript? I'm having a hard time taking a screenshot of this menu while it's actually open, but I'm looking for what the curly-brace menu shows you here:

image

E.g., I'd expect it to be 5.3.2 or so.

asp3 commented 4 months ago

@svidgen Yep, its 5.3.2

image
svidgen commented 4 months ago

Gotcha. Thanks for checking. Leaving in pending triage for @nadetastic to try to repro and/or ask followups.

david-mcafee commented 4 months ago

@asp3 - could you also give us an idea of the size of your schema? Specifically, is your schema particularly large (many models, or many fields per model), or complex (complex auth rules, a high degree of model connections, etc)? Thank you!!

iartemiev commented 4 months ago

@asp3 - I'm able to repro this. The workaround you're using asserting as V6ClientSSRCookies is perfectly valid and I would just stick with that while we look into improving the underlying types.

jamespoyser commented 4 months ago

OMG. I've solved SO many issues I've been having with Amplify by changing the TS version in VS Code - I was getting the same error on the line:

export type Schema = ClientSchema<typeof schema>;

in resource.ts

But more annoyingly, calls like this:

await client.models.MyModel.update(...)

had no type information - accepts and returns 'any'.

All of this goes away by changing the VS code TS version.]

One for a list of FAQs / common issues, perhaps?

patorpey commented 2 months ago

In the process of porting an Amplify app to TypeScript, I am experiencing this issue when passing a generated Client instance to a function. The function is declared as:

import {generateClient, type Client} from "aws-amplify/api";

function doSomething(client: Client) {
    return {};
}

// When called:
const client = generateClient();
doSomething(client);
         // ^ Type instantiation is excessively deep and possibly infinite.ts(2589)
         //    const client: V6Client<never>

Similarly for server-side clients:

import {generateServerClientUsingCookies, type ClientUsingSSRCookies} from '@aws-amplify/adapter-nextjs/api';
import {cookies} from "next/headers";
import amplifyconfig from "../../src/amplifyconfiguration.json";

function doSomething(client: ClientUsingSSRCookies) {
    return {};
}

// When called:
const client = generateServerClientUsingCookies({
    config: amplifyconfig,
    cookies
});
doSomething(client);
         // ^ Type instantiation is excessively deep and possibly infinite.ts(2589)
         //    const client: V6ClientSSRCookies<never>

Note that ideally the type for the argument to the function be Client, but Client is not a strict supertype of the V6ClientSSRCookies<never> returned from generateServerClientUsingCookies() (i.e. V6ClientSSRCookies<never> is not assignable to the parameter of type Client since subscriptions don't exist on the server).

Also, per @asp3's and @iartemiev's comments, I am unable to see if explicitly declaring the type of the client to be V6ClientSSRCookies resolves the issue, since that type (along with other useful "reference" types used internally) are not exported. So I cannot import that type for use. I'm curious as to how you are able to access those types, given the recommended way of using aws-amplify category APIs in V6. The seemingly closest exported type is ClientUsingSSRCookies, which is shown above. I assume this is the correct consumer-facing type for this usage.

aws-amplify: 6.0.27 @aws-amplify/adapter-nextjs: 1.0.27 typescript: 5.4.4 VSCode: 1.87.2 The VSCode workspace is configured to use the project's version of TypeScript.

ChristopherGabba commented 1 month ago

+1 on this issue. I solved it by upgrading my typescript version to 5.4.5. Note to all who join, that amplify gen 2 basically infers nothing at all without a later version of typescript.