4

I'm not sure what changed, maybe it is even related to babel, but I started getting errors like UserControler_1 is undefined when I use things like this

UserControler.ts

export function signOut() { console.log("Sign Out") }

Page.tsx

import * as React from "react;
import { signOut } from "./UserControler";
import { TouchableWithoutFeedback, Text } from "react-native";

class Page extends React.Component {
  _signOut = () => signOut()

  render() {
    return (
      <TouchableWithoutFeedback onPress={this._signOut}>
         <Text>Sign Out</Text>
      </TouchableWithoutFeedback>
    )
  }
}

Above results in error like this

UserControler_1 is undefined

Sometimes it errors more specifically i.e.

Can't find variable: signOut

Weirdest thing is that if I change code to something like this, it works fine

import * as React from "react;
import { signOut } from "./UserControler";

class Page extends React.Component {    
  render() {
    return (
     <TouchableWithoutFeedback onPress={() => signOut}>
       <Text>Sign Out</Text>
     </TouchableWithoutFeedback>
    )
  }
}

Very confused here

My tsconfig

{
  "compilerOptions": {
    "moduleResolution": "node",
    "module": "es6",
    "target": "es6",
    "lib": ["es7"],
    "allowJs": true,
    "checkJs": true,
    "jsx": "react-native",
    "removeComments": true,
    "outDir": "./dist",
    "typeRoots": ["node_modules/@types", "./typings"],
    "noFallthroughCasesInSwitch": true,
    "noImplicitReturns": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "allowSyntheticDefaultImports": true,
    "strict": true
  },
  "exclude": ["./node_modules", "./android", "./ios", "./__tests__", "./dist", "./__mocks__"],
  "include": ["./src"]
}

This builds into dist folder from where babel draws its files and hence makes application work, my babelrc

{
  "presets": ["react-native"]
}
14
  • the reason for the second code working (the button) is that you are assigning signOut [undefined] to onClick which means it does nothing. in the first example, you are executing signOut() which means it gives an error, since signOut doesn't exist. This is not an answer to your problem, just the reason why one bugs out, and two doesn't :-) Commented Feb 13, 2018 at 15:05
  • @DoXicK updated examples to be consistent, thing is that second version also executes signOut as expected Commented Feb 13, 2018 at 15:08
  • and it is the exact same path ? Commented Feb 13, 2018 at 15:10
  • @DoXicK exact same import yeh Commented Feb 13, 2018 at 15:11
  • then it probably is a circular reference somewhere. I've had this before where file A loads B, B loads C, C loads A. Which meant that the export from A in C were not exposed yet as you imported C. Commented Feb 13, 2018 at 15:16

2 Answers 2

1
+150

It seems to be a typescript bug introduces in 2.7.1 - it was very annoying, but good thing is that upgrading to 2.7.2 fixes it. (At least it fixed the issue I experienced).

More info: https://github.com/Microsoft/TypeScript/issues/21478

Sign up to request clarification or add additional context in comments.

Comments

1
<TouchableWithoutFeedback onPress={() => signOut}>

Works because you are returning the reference to signOut, the function you imported above. The important thing to note is that => whatever returns whatever.

 _signOut = () => signOut()

  render() {
    return (
      <TouchableWithoutFeedback onPress={this._signOut}>

Doesn't work because in _signOut you use another arrow function but this time it returns signOut(), which is invoked right then and there. The weirdness you're seeing probably comes from that fact that at some points that function may not have been imported by the time it's hitting your code and invoking the function.

so the solution is something like this

 _signOut = () => signOut

  render() {
    return (
      <TouchableWithoutFeedback onPress={this._signOut}>

By not invoking the function like you were doing previously, everything works as expected.

Check out this excellent explanation of how to use arrow fuctions inside react: https://stackoverflow.com/a/48700540/214347

1 Comment

It's also nice to just execute as <TouchableWithoutFeedback onPress={signOut}> without the parentheses at all, if there's no parameter need to be passed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.