software-mansion / react-native-gesture-handler

Declarative API exposing platform native touch and gesture system to React Native.
https://docs.swmansion.com/react-native-gesture-handler/
MIT License
5.85k stars 954 forks source link

fix: npm publish with tsc build error 'Object posible may be undefined' #2867

Closed krmao closed 3 weeks ago

krmao commented 3 weeks ago

Description

fix: npm publish with tsc build error 'Object posible may be undefined'

m-bert commented 3 weeks ago

Hi! Could you share some logs that show this error? I've run yarn tsc --noEmit and yarn tsc --build and I haven't seen any error.

krmao commented 3 weeks ago

@m-bert logs shown

devDependencies

  "devDependencies": {
    "@commitlint/config-conventional": "^17.0.2",
    "@evilmartians/lefthook": "^1.5.0",
    "@react-native/babel-preset": "^0.74.0",
    "@react-native/eslint-config": "^0.72.2",
    "@release-it/conventional-changelog": "^5.0.0",
    "@types/crypto-js": "^4.2.2",
    "@types/jest": "^28.1.2",
    "@types/react": "~17.0.21",
    "@types/react-native": "0.70.0",
    "commitlint": "^17.0.2",
    "crypto-js": "^4.2.0",
    "del-cli": "^5.0.0",
    "eslint": "^8.4.1",
    "eslint-config-prettier": "^8.5.0",
    "eslint-plugin-prettier": "^4.0.0",
    "jest": "^28.1.1",
    "patch-package": "^8.0.0",
    "prettier": "^2.0.5",
    "react": "18.2.0",
    "react-native": "0.72.10",
    "react-native-builder-bob": "^0.23.2",
    "react-native-gesture-handler": "~2.16.0",
    "react-native-get-random-values": "^1.11.0",
    "react-native-reanimated": "~3.3.0",
    "release-it": "^15.0.0",
    "typescript": "^5.0.2"
  },
  "resolutions": {
    "@types/react": "17.0.21"
  },

env

node -v
        v18.16.1
cd xxxlibraryproject
rm -rf patches
rm -rf node_modules
rm -rf example/node_modules
yarn install --check-cache

yarn tsc --noEmit

node_modules/react-native-gesture-handler/src/handlers/PanGestureHandler.ts:207:6 - error TS2532: Object is possibly 'undefined'.

207     (props.activeOffsetX[0] > 0 || props.activeOffsetX[1] < 0)
         ~~~~~~~~~~~~~~~~~~~~~~

node_modules/react-native-gesture-handler/src/handlers/PanGestureHandler.ts:207:36 - error TS2532: Object is possibly 'undefined'.

207     (props.activeOffsetX[0] > 0 || props.activeOffsetX[1] < 0)
                                       ~~~~~~~~~~~~~~~~~~~~~~

node_modules/react-native-gesture-handler/src/handlers/PanGestureHandler.ts:216:6 - error TS2532: Object is possibly 'undefined'.

216     (props.activeOffsetY[0] > 0 || props.activeOffsetY[1] < 0)
         ~~~~~~~~~~~~~~~~~~~~~~

node_modules/react-native-gesture-handler/src/handlers/PanGestureHandler.ts:216:36 - error TS2532: Object is possibly 'undefined'.

216     (props.activeOffsetY[0] > 0 || props.activeOffsetY[1] < 0)
                                       ~~~~~~~~~~~~~~~~~~~~~~

node_modules/react-native-gesture-handler/src/handlers/PanGestureHandler.ts:225:6 - error TS2532: Object is possibly 'undefined'.

225     (props.failOffsetX[0] > 0 || props.failOffsetX[1] < 0)
         ~~~~~~~~~~~~~~~~~~~~

node_modules/react-native-gesture-handler/src/handlers/PanGestureHandler.ts:225:34 - error TS2532: Object is possibly 'undefined'.

225     (props.failOffsetX[0] > 0 || props.failOffsetX[1] < 0)
                                     ~~~~~~~~~~~~~~~~~~~~

node_modules/react-native-gesture-handler/src/handlers/PanGestureHandler.ts:234:6 - error TS2532: Object is possibly 'undefined'.

234     (props.failOffsetY[0] > 0 || props.failOffsetY[1] < 0)
         ~~~~~~~~~~~~~~~~~~~~

node_modules/react-native-gesture-handler/src/handlers/PanGestureHandler.ts:234:34 - error TS2532: Object is possibly 'undefined'.

234     (props.failOffsetY[0] > 0 || props.failOffsetY[1] < 0)
                                     ~~~~~~~~~~~~~~~~~~~~

node_modules/react-native-gesture-handler/src/utils.ts:22:31 - error TS2345: Argument of type 'Transformed | null | undefined' is not assignable to parameter of type 'Transformed | null'.
  Type 'undefined' is not assignable to type 'Transformed | null'.

22     const transformed = mapFn(previous, current);
                                 ~~~~~~~~

Found 9 errors in 2 files.

yarn tsc --build

node_modules/react-native-gesture-handler/src/utils.ts:22:31 - error TS2345: Argument of type 'Transformed | null | undefined' is not assignable to parameter of type 'Transformed | null'.
  Type 'undefined' is not assignable to type 'Transformed | null'.

22     const transformed = mapFn(previous, current);
                                 ~~~~~~~~

node_modules/react-native-gesture-handler/src/handlers/PanGestureHandler.ts:207:6 - error TS2532: Object is possibly 'undefined'.

207     (props.activeOffsetX[0] > 0 || props.activeOffsetX[1] < 0)
         ~~~~~~~~~~~~~~~~~~~~~~

node_modules/react-native-gesture-handler/src/handlers/PanGestureHandler.ts:207:36 - error TS2532: Object is possibly 'undefined'.

207     (props.activeOffsetX[0] > 0 || props.activeOffsetX[1] < 0)
                                       ~~~~~~~~~~~~~~~~~~~~~~

node_modules/react-native-gesture-handler/src/handlers/PanGestureHandler.ts:216:6 - error TS2532: Object is possibly 'undefined'.

216     (props.activeOffsetY[0] > 0 || props.activeOffsetY[1] < 0)
         ~~~~~~~~~~~~~~~~~~~~~~

node_modules/react-native-gesture-handler/src/handlers/PanGestureHandler.ts:216:36 - error TS2532: Object is possibly 'undefined'.

216     (props.activeOffsetY[0] > 0 || props.activeOffsetY[1] < 0)
                                       ~~~~~~~~~~~~~~~~~~~~~~

node_modules/react-native-gesture-handler/src/handlers/PanGestureHandler.ts:225:6 - error TS2532: Object is possibly 'undefined'.

225     (props.failOffsetX[0] > 0 || props.failOffsetX[1] < 0)
         ~~~~~~~~~~~~~~~~~~~~

node_modules/react-native-gesture-handler/src/handlers/PanGestureHandler.ts:225:34 - error TS2532: Object is possibly 'undefined'.

225     (props.failOffsetX[0] > 0 || props.failOffsetX[1] < 0)
                                     ~~~~~~~~~~~~~~~~~~~~

node_modules/react-native-gesture-handler/src/handlers/PanGestureHandler.ts:234:6 - error TS2532: Object is possibly 'undefined'.

234     (props.failOffsetY[0] > 0 || props.failOffsetY[1] < 0)
         ~~~~~~~~~~~~~~~~~~~~

node_modules/react-native-gesture-handler/src/handlers/PanGestureHandler.ts:234:34 - error TS2532: Object is possibly 'undefined'.

234     (props.failOffsetY[0] > 0 || props.failOffsetY[1] < 0)
                                     ~~~~~~~~~~~~~~~~~~~~

Found 9 errors.

npm publish --access=public

npm ERR! code 1
npm ERR! path /Users/kr.mao/workspace/react-native-captcha
npm ERR! command failed
npm ERR! command sh -c bob build
npm ERR! ℹ Building target commonjs
npm ERR! ℹ Cleaning up previous build at lib/commonjs
npm ERR! ℹ Compiling 23 files in src with babel
npm ERR! ✔ Wrote files to lib/commonjs
npm ERR! ℹ Building target module
npm ERR! ℹ Cleaning up previous build at lib/module
npm ERR! ℹ Compiling 23 files in src with babel
npm ERR! ✔ Wrote files to lib/module
npm ERR! ℹ Building target typescript
npm ERR! ℹ Cleaning up previous build at lib/typescript
npm ERR! ℹ Generating type definitions with tsc
npm ERR! node_modules/react-native-gesture-handler/src/handlers/PanGestureHandler.ts:207:6 - error TS2532: Object is possibly 'undefined'.
npm ERR!
npm ERR! 207     (props.activeOffsetX[0] > 0 || props.activeOffsetX[1] < 0)
npm ERR!          ~~~~~~~~~~~~~~~~~~~~~~
npm ERR!
npm ERR! node_modules/react-native-gesture-handler/src/handlers/PanGestureHandler.ts:207:36 - error TS2532: Object is possibly 'undefined'.
npm ERR!
npm ERR! 207     (props.activeOffsetX[0] > 0 || props.activeOffsetX[1] < 0)
npm ERR!                                        ~~~~~~~~~~~~~~~~~~~~~~
npm ERR!
npm ERR! node_modules/react-native-gesture-handler/src/handlers/PanGestureHandler.ts:216:6 - error TS2532: Object is possibly 'undefined'.
npm ERR!
npm ERR! 216     (props.activeOffsetY[0] > 0 || props.activeOffsetY[1] < 0)
npm ERR!          ~~~~~~~~~~~~~~~~~~~~~~
npm ERR!
npm ERR! node_modules/react-native-gesture-handler/src/handlers/PanGestureHandler.ts:216:36 - error TS2532: Object is possibly 'undefined'.
npm ERR!
npm ERR! 216     (props.activeOffsetY[0] > 0 || props.activeOffsetY[1] < 0)
npm ERR!                                        ~~~~~~~~~~~~~~~~~~~~~~
npm ERR!
npm ERR! node_modules/react-native-gesture-handler/src/handlers/PanGestureHandler.ts:225:6 - error TS2532: Object is possibly 'undefined'.
npm ERR!
npm ERR! 225     (props.failOffsetX[0] > 0 || props.failOffsetX[1] < 0)
npm ERR!          ~~~~~~~~~~~~~~~~~~~~
npm ERR!
npm ERR! node_modules/react-native-gesture-handler/src/handlers/PanGestureHandler.ts:225:34 - error TS2532: Object is possibly 'undefined'.
npm ERR!
npm ERR! 225     (props.failOffsetX[0] > 0 || props.failOffsetX[1] < 0)
npm ERR!                                      ~~~~~~~~~~~~~~~~~~~~
npm ERR!
npm ERR! node_modules/react-native-gesture-handler/src/handlers/PanGestureHandler.ts:234:6 - error TS2532: Object is possibly 'undefined'.
npm ERR!
npm ERR! 234     (props.failOffsetY[0] > 0 || props.failOffsetY[1] < 0)
npm ERR!          ~~~~~~~~~~~~~~~~~~~~
npm ERR!
npm ERR! node_modules/react-native-gesture-handler/src/handlers/PanGestureHandler.ts:234:34 - error TS2532: Object is possibly 'undefined'.
npm ERR!
npm ERR! 234     (props.failOffsetY[0] > 0 || props.failOffsetY[1] < 0)
npm ERR!                                      ~~~~~~~~~~~~~~~~~~~~
npm ERR!
npm ERR! node_modules/react-native-gesture-handler/src/utils.ts:22:31 - error TS2345: Argument of type 'Transformed | null | undefined' is not assignable to parameter of type 'Transformed | null'.
npm ERR!   Type 'undefined' is not assignable to type 'Transformed | null'.
npm ERR!
npm ERR! 22     const transformed = mapFn(previous, current);
npm ERR!                                  ~~~~~~~~
npm ERR!
npm ERR!
npm ERR! Found 9 errors in 2 files.
npm ERR!
npm ERR! Errors  Files
npm ERR!      8  node_modules/react-native-gesture-handler/src/handlers/PanGestureHandler.ts:207
npm ERR!      1  node_modules/react-native-gesture-handler/src/utils.ts:22
npm ERR! ✖ Failed to build definition files.
npm ERR! bob build
npm ERR!
npm ERR! build files for publishing
npm ERR!
npm ERR! 选项:
npm ERR!   --help     显示帮助信息                                                 [布尔]
npm ERR!   --version  显示版本号                                                   [布尔]
npm ERR!
npm ERR! Error: Failed to build definition files.
npm ERR!     at build (/Users/kr.mao/workspace/react-native-captcha/node_modules/react-native-builder-bob/lib/targets/typescript.js:147:11)
npm ERR!     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
npm ERR!     at async Object.handler (/Users/kr.mao/workspace/react-native-captcha/node_modules/react-native-builder-bob/lib/index.js:324:9)

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/kr.mao/.npm/_logs/2024-04-17T10_05_35_422Z-debug-0.log
m-bert commented 3 weeks ago

It looks like something is wrong with your setup. Array.isArray is an assertion and TypeScript should see that. Here you can see full signature:

interface ArrayConstructor {
    ...
    isArray(arg: any): arg is any[];
    ...
}

Can you check that in your environment? You can do this by clicking on isArray with ctrl (or cmd on macOS). Also, we use TypeScript 5.0.4, you can try upgrading to this version

krmao commented 3 weeks ago
image

yes, isArray(arg: any): arg is any[]; can check props.activeOffsetX is array or is undefined, but props.activeOffsetX [0] may be undefined

the error is same as "typescript": "^5.0.4"

m-bert commented 3 weeks ago

Okay, now I see. My guess is that you have strictNullChecks enabled in tsconfig.json (we thought that strict enables it by default).

We want these problems to be solved in different manner, but we also want to give you opportunity to contribute to our library.

Unfortunately I cannot verify it in our repo even after adding strictNullChecks. However, I've tested first change on TSPlayground and it seems to work.

krmao commented 3 weeks ago

I didn't set strictNullChecks in tsconfig.json

{
  "compilerOptions": {
    "rootDir": ".",
    "paths": {
      "react-native-captcha": ["./src/index"]
    },
    "allowUnreachableCode": false,
    "allowUnusedLabels": false,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "jsx": "react",
    "lib": ["esnext"],
    "module": "esnext",
    "moduleResolution": "node",
    "noFallthroughCasesInSwitch": true,
    "noImplicitReturns": true,
    "noImplicitUseStrict": false,
    "noStrictGenericChecks": false,
    "noUncheckedIndexedAccess": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "resolveJsonModule": true,
    "skipLibCheck": true,
    "strict": true,
    "target": "esnext"
  },
  "exclude": ["node_modules", "examples/node_modules"]
}

but if set strictNullChecks false,

will got another two errors

yarn tsc --build
node_modules/react-native-gesture-handler/src/handlers/createHandler.tsx:133:3 - error TS7018: Object literal's property '[State.UNDETERMINED]' implicitly has an 'any' type.

133   [State.UNDETERMINED]: undefined,
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

node_modules/react-native-gesture-handler/src/handlers/createHandler.tsx:288:48 - error TS7053: Element implicitly has an 'any' type because expression of type 'any' can't be used to index type 'Readonly<T & InternalEventHandlers> & Readonly<{ children?: ReactNode; }>'.

288         const eventHandler = stateEventName && this.props[stateEventName];
                                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~

Found 2 errors.

so I removed strictNullChecks, and change activeOffsetY and activeOffsetX and failOffsetY and failOffsetX type, everything works perfectly as you said, it works like a charm!

Even if npm publish everything works last week, but this week got error, I don't know why.

Yan can just commit it, I will close this pull request now .

m-bert commented 3 weeks ago

So if I understood correctly, the only thing that you had to change were the type of activeOffsetX, ...? Or was it necessary to add casting mentioned in second bullet? (const previous = previousArr[i] as Transformed | null)?

krmao commented 3 weeks ago

here is my react-native-gesture-handler+2.16.0.patch

diff --git a/node_modules/react-native-gesture-handler/src/handlers/PanGestureHandler.ts b/node_modules/react-native-gesture-handler/src/handlers/PanGestureHandler.ts
index c596535..b861839 100644
--- a/node_modules/react-native-gesture-handler/src/handlers/PanGestureHandler.ts
+++ b/node_modules/react-native-gesture-handler/src/handlers/PanGestureHandler.ts
@@ -150,7 +150,7 @@ export interface PanGestureHandlerProps
    * to 0. If only one number `p` is given a range of `(-inf, p)` will be used
    * if `p` is higher or equal to 0 and `(-p, inf)` otherwise.
    */
-  activeOffsetY?: number | number[];
+  activeOffsetY?: number | [left:number, right: number];

   /**
    * Range along X axis (in points) where fingers travels without activation of
@@ -160,7 +160,7 @@ export interface PanGestureHandlerProps
    * to 0. If only one number `p` is given a range of `(-inf, p)` will be used
    * if `p` is higher or equal to 0 and `(-p, inf)` otherwise.
    */
-  activeOffsetX?: number | number[];
+  activeOffsetX?: number | [left:number, right: number];

   /**
    * When the finger moves outside this range (in points) along Y axis and
@@ -170,7 +170,7 @@ export interface PanGestureHandlerProps
    * to 0. If only one number `p` is given a range of `(-inf, p)` will be used
    * if `p` is higher or equal to 0 and `(-p, inf)` otherwise.
    */
-  failOffsetY?: number | number[];
+  failOffsetY?: number | [left:number, right: number];

   /**
    * When the finger moves outside this range (in points) along X axis and
@@ -180,7 +180,7 @@ export interface PanGestureHandlerProps
    * to 0. If only one number `p` is given a range of `(-inf, p)` will be used
    * if `p` is higher or equal to 0 and `(-p, inf)` otherwise.
    */
-  failOffsetX?: number | number[];
+  failOffsetX?: number | [left:number, right: number];
 }

 export const panHandlerName = 'PanGestureHandler';
diff --git a/node_modules/react-native-gesture-handler/src/utils.ts b/node_modules/react-native-gesture-handler/src/utils.ts
index 6ab5c61..f4daef0 100644
--- a/node_modules/react-native-gesture-handler/src/utils.ts
+++ b/node_modules/react-native-gesture-handler/src/utils.ts
@@ -18,7 +18,7 @@ export function withPrevAndCurrent<T, Transformed>(
   const currentArr = [...array];
   const transformedArr: Transformed[] = [];
   currentArr.forEach((current, i) => {
-    const previous = previousArr[i];
+    const previous = previousArr[i] as Transformed | null;
     const transformed = mapFn(previous, current);
     previousArr.push(transformed);
     transformedArr.push(transformed);