aws-amplify / amplify-ui

Amplify UI is a collection of accessible, themeable, performant React (and more!) components that can connect directly to the cloud.
https://ui.docs.amplify.aws
Apache License 2.0
909 stars 289 forks source link

Cannot compile when TS Strict is enabled #3254

Closed jbowen28 closed 1 year ago

jbowen28 commented 1 year ago

Before creating a new issue, please confirm:

On which framework/platform are you having an issue?

React

Which UI component?

Authenticator

How is your app built?

CRA

What browsers are you seeing the problem on?

Chrome

Please describe your bug.

I am compiling a CRA typescript monorepo project with aws-amplify and @aws-amplify/ui-react components. I am getting the following errors in the @aws-amplify/ui-react component:

jamesbowen@Jamess-MBP atlas-ui % yarn build
yarn run v1.22.17
warning package.json: No license field
$ rimraf ./lib && tsc
../../node_modules/@aws-amplify/ui-react/dist/types/components/Geo/LocationSearch/index.d.ts:1:37 - error TS2307: Cannot find module 'maplibre-gl-geocoder' or its corresponding type declarations.

1 import { LocationSearchProps } from 'maplibre-gl-geocoder';
                                      ~~~~~~~~~~~~~~~~~~~~~~

../../node_modules/@aws-amplify/ui-react/dist/types/primitives/types/responsive.d.ts:2:56 - error TS2339: Property 'values' does not exist on type 'PartialObjectDeep<Breakpoints> | undefined'.

2 export declare type Breakpoints = Theme['breakpoints']['values'];
                                                         ~~~~~~~~

../../node_modules/@aws-amplify/ui-react/dist/types/primitives/types/responsive.d.ts:3:61 - error TS2339: Property 'values' does not exist on type 'PartialObjectDeep<Breakpoints> | undefined'.

3 export declare type Breakpoint = keyof Theme['breakpoints']['values'];
                                                              ~~~~~~~~

I looked at the github code for @aws-amplify/ui-react@4.3.2 and these errors look legitimate.

What's the expected behaviour?

No errors compiling.

Help us reproduce the bug!

Here are the node module dependencies from my package.json file:

    "dependencies": {
        "@date-io/date-fns": "1.x",
        "@redux-devtools/extension": "^3.2.2",
        "axios": "^0.21.2",
        "classnames": "^2.2.6",
        "connected-react-router": "^6.5.2",
        "date-fns": "^2.12.0",
        "date-fns-tz": "^1.0.10",
        "jest": "^29.0.0",
        "js-base64": "^2.5.2",
        "jsoneditor": "^9.7.4",
        "jsoneditor-react": "^3.1.2",
        "query-string": "^6.8.3",
        "react-redux": "^7.1.1",
        "recharts": "^2.2.0",
        "redux": "^4.0.4",
        "redux-logger": "^3.0.6",
        "redux-saga": "^1.1.2",
        "timers-browserify": "^2.0.12",
        "timezone-support": "^3.1.0",
        "webpack": "^5.0.0",
        "yup": "^0.28.4"
    },
    "peerDependencies": {
        "@aws-amplify/ui-react": "^4.3.0",
        "@azure/msal-browser": "^2.22.0",
        "@azure/msal-react": "^1.3.0",
        "@material-ui/core": "^4.9.7",
        "@material-ui/icons": "^4.9.1",
        "@material-ui/pickers": "^3.2.10",
        "@material-ui/styles": "^4.9.6",
        "aws-amplify": "^5.0.7",
        "formik": "^2.2.9",
        "prop-types": "^15.7.2",
        "react": "^16.13.1",
        "react-dom": "^16.13.1",
        "react-native": "^0.71.0-rc.5",
        "react-router-dom": "^5.1.2"
    },
    "devDependencies": {
        "@aws-amplify/ui-react": "^4.3.0",
        "@azure/msal-browser": "^2.22.0",
        "@azure/msal-react": "^1.3.0",
        "@babel/core": "^7.6.0",
        "@material-ui/core": "^4.9.7",
        "@material-ui/icons": "^4.9.1",
        "@material-ui/lab": "^4.0.0-alpha.28",
        "@material-ui/pickers": "^3.2.10",
        "@storybook/addon-actions": "^5.1.11",
        "@storybook/addon-links": "^5.1.11",
        "@storybook/react": "^6.0.0",
        "@types/axios": "^0.14.0",
        "@types/classnames": "^2.2.9",
        "@types/enzyme": "^3.10.3",
        "@types/enzyme-adapter-react-16": "^1.0.5",
        "@types/jest": "^29.0.0",
        "@types/material-ui": "^0.21.7",
        "@types/node": "13.11.1",
        "@types/prop-types": "^15.7.3",
        "@types/react": "^17.0.14",
        "@types/react-dom": "17.0.14",
        "@types/react-redux": "^7.1.5",
        "@types/react-router-dom": "^5.1.0",
        "@types/redux": "^3.6.0",
        "@types/redux-saga": "^0.10.5",
        "@types/yup": "^0.28.0",
        "aws-amplify": "^5.0.7",
        "enzyme": "^3.10.0",
        "enzyme-adapter-react-16": "^1.14.0",
        "formik": "2.2.9",
        "husky": "^8.0.2",
        "react-router-dom": "^5.1.2",
        "react-test-renderer": "^16.10.2",
        "rimraf": "^3.0.0",
        "ts-jest": "^29.0.0",
        "typescript": "4.4.4"
    } 

Here are the related tsconfig.json files for this monorepo project:

{
    "compilerOptions": {
        /* Basic Options */
        "target": "es6",
        "module": "esnext",
        "lib": ["dom", "dom.iterable", "esnext"],
        "jsx": "react",
        "resolveJsonModule": true,
        "forceConsistentCasingInFileNames": true,
        "declaration": true /* Instructs the compiler to generate declaration (.d.ts) files */,
        "declarationMap": true,
        "allowJs": false /* Allow javascript files to be compiled. Incompatible with "declaration": true */,

        /* Strict Type-Checking Options */
        "strict": true /* Enable all strict type checking options (noImplicitAny, noImplicitThis, etc.) */,
        "noImplicitAny": false /* Raise error on expressions and declarations with an implied 'any' type. */,

        /* Module Resolution Options */
        "moduleResolution": "node",
        "allowSyntheticDefaultImports": true /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */,
        "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports */
    }
}

{
    "extends": "../../tsconfig.json",
    "compilerOptions": {
        "outDir": "lib",
        "rootDir": "src",
        /*"allowJs": true*/
        "allowJs": false /* this must be false when TS is configured to generate declaration files */
    },
    "include": ["src"],
    "exclude": [
        "**/*.spec.ts",
        "**/*.spec.tsx",
        "**/*.spec.js",
        "**/*.spec.jsx",
        "**/testSetup.ts",
        "**/.deprecated"
    ]
}

Code Snippet

// Put your code below this line.
import React, { useState, useEffect } from 'react'
import { Amplify } from 'aws-amplify'
import { Authenticator } from '@aws-amplify/ui-react'
import { Typography } from '@material-ui/core'
import {
    Middleware,
    defaultAtlasTheme,
} from '../..'
import {
    AWSLoginPage,
    configureAWSAuthProvider,
} from '.'
import '@aws-amplify/ui-react/styles.css'

Amplify.configure({
    Auth: {
        region: window.env.REACT_APP_AWS_REGION,
        userPoolId: window.env.REACT_APP_USER_POOL_ID,
        userPoolWebClientId: window.env.REACT_APP_USER_POOL_WEB_CLIENT_ID,
    },
})

export const authProvider = configureAWSAuthProvider()

const awsTheme = {
    button: { backgroundColor: '#0095C8' },
    a: { color: '#0095C8' },
}

const atlasTheme = defaultAtlasTheme()

const CheckAuthenticated = (props) => {
    const [localState, setLocalState] = useState<string>('')
  const [ authData, setAuthData] = useState<any>(null)

  useEffect(() => {
    getAuthData()  
  }, [localState])

  const getAuthData = async () => {
    try {
      const authDataLocal = await authProvider.checkAuth()
      setAuthData(authDataLocal)
    } catch (e) {
      console.log('CheckAuthenticated exception: ', e)
    }
  }

    const onStateChange = (state: string, params: {}) => {
        setLocalState(state)
    }

    if (authData?.loggedInUser) {
        return <>{props.children}</>
    } else {
        return (
            <AWSLoginPage
                atlasTheme={atlasTheme}
                copyright="Sky Republic"
                title={
                    <Typography variant="h6" gutterBottom align="center">
                        Atlas Admin Console
                    </Typography>
                }
                onStateChange={onStateChange}
            />
        )
    }
}

export const AuthMiddleware: Middleware = ({ children }) => (
    <Authenticator.Provider>
        <CheckAuthenticated>{children}</CheckAuthenticated>
    </Authenticator.Provider>
)

Additional information and screenshots

I created a similar issue (#3208) about 2 weeks ago and removed the maplibre... module dependencies as @reesscot recommended and added "@babel/plugin-transform-block-scoping": "7.20.5" (to fix issue aws-amplify/amplify-ui#3210) to my root package.json resolutions section. Somehow, that seemed to fix the exact same compiler errors. But 2 weeks and a couple minor/patch versions later, the compiler issues have appeared again.

reesscot commented 1 year ago

Hi @jbowen28, it looks like you have your TS config set with "strict": true. We are working on updating our types to fully support strict type checking throughout our library, but in the meantime the workaround is to set skipLibCheck to true.

 "compilerOptions": {
    "skipLibCheck": true,

We will keep the following issue up to date with our progress.

jbowen28 commented 1 year ago

Got it. Please keep me updated as this is pretty important.

reesscot commented 1 year ago

@jbowen28 We've made a number of TS Strict fixes including the ones you mentioned in your error message. Would you please try out the latest version of @aws-amplify/ui-react and let us know if you are still getting errors?

npm install @aws-amplify/ui-react@latest
reesscot commented 1 year ago

@jbowen28 And anyone else following this issue may be interested in commenting on the Amplify JS RFC around better TypeScript support: https://github.com/aws-amplify/amplify-js/issues/11113

reesscot commented 1 year ago

Closing out as these TS errors are fixed now.