简体   繁体   中英

Getting "Invalid call" when using require with Typescript and Expo

I am trying to play some audio in a react-native app created with the expo-cli.

The code is written in typescript and the offending code looks like this, taken from the expo.io documentation :

import * as React from 'react'
import { WorkoutComponent } from "./WorkoutExecutor";
import { Audio } from 'expo';

export default class AudioPlayer {

    private async playAudio(fileName: string) {
        console.log("Playing Audio: " + fileName);
        const soundFile = './assets/sounds/' + fileName + '.mp3';
        try {
            const { sound: soundObject, status } = await Audio.Sound.createAsync(
              require(soundFile),
              { shouldPlay: true }
            );
            // Your sound is playing!
          } catch (error) {
              console.log(error);
            // An error occurred!
          }

    }
[...]
}

When the app loads, it gives the following error, even before it gets to the screen with the sound

[...]\src\AudioPlayer.ts:Invalid call at line 13: require(soundFile)

I realize that the coe example is with javascript and not typescript, but what am I missing?

My tsconfig.json is the one from the expo typescript example and looks like this

{
  "compilerOptions": {
    "baseUrl": "./src",
    "esModuleInterop": true,
    "experimentalDecorators": true,
    "forceConsistentCasingInFileNames": true,
    "importHelpers": true,
    "jsx": "react-native",
    "module": "es2015",
    "moduleResolution": "node",
    "noEmitHelpers": true,
    "noImplicitReturns": true,
    "noUnusedLocals": true,
    // Using the type definitions in @types/expo becuase they are still better than the ones provided by expo. See SvgScreen.tsx and SystemFontsScreen.tsx.
    "paths": {
      "expo": [
        "../node_modules/@types/expo",
        "../node_modules/expo"
      ],
    },
    "skipLibCheck": true,
    "strict": true,
    "target": "es2017"
  },
  "exclude": [
    "node_modules"
  ]
}

I got help via Twitter, and the problem is that require() does not work with dynamic values. This also explains why the errors happened before the app was even loaded, as it tried to resolve the require at build or load time and not at runtime as I had thought.

import * as React from 'react'
import { WorkoutComponent } from "./WorkoutExecutor";
import { Audio } from 'expo';

const fileA = require('path/to/sound/file.mp3');
const fileB = require('path/to/sound/file2.mp3');

export default class AudioPlayer {

    private async playAudio(fileName: string) {
       if (fileName == 'A') {
           var soundFile = fileA;
       } else {
           var soundFile = fileB;
       }
       try {
          const { sound: soundObject, status } = await Audio.Sound.createAsync(
          soundFile,
          { shouldPlay: true }
        );
        // Your sound is playing!
      } catch (error) {
          console.log(error);
        // An error occurred!
      }

}
[...]
}

我通过使用修复了它

import song from "./path_to_song/song.mp3"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM