React Native Sound のtypescript Error を修正する
Purpose (目的)
React Nativeで音を出したい。
しかし、サンプルの通りやると、typescript のErrorが出るので直したい。
Environment (動作環境)
React Native (version 0.68.2)
expo (version 45.0.8)
Typescript (version 4.3.5)
npm install
インストールします。(npmではなくexpoでインストールすると、互換性とかを修正してくれるらしい)
expo install expo-av
元々のコード
Expoの公式のコードと同じです。(https://docs.expo.dev/versions/latest/sdk/audio/)
このコードをtypescriptで書くとErrorが出るので修正します。
修正前
import * as React from 'react';
import { Text, View, StyleSheet, Button } from 'react-native';
import { Audio } from 'expo-av';
export default function App() {
const [sound, setSound] = React.useState();
async function playSound() {
console.log('Loading Sound');
const { sound } = await Audio.Sound.createAsync(
require('./assets/Hello.mp3')
);
setSound(sound);
console.log('Playing Sound');
await sound.playAsync();
}
React.useEffect(() => {
return sound
? () => {
console.log('Unloading Sound');
sound.unloadAsync(); }
: undefined;
}, [sound]);
return (
<View>
<Button title="Play Sound" onPress={playSound} />
</View>
);
}
エラーの内容
Property 'unloadAsync’ does not exist on type 'never’.ts(2339)
Argument of type 'Sound’ is not assignable to parameter of type 'SetStateAction<undefined>’.
Type 'Sound’ provides no match for the signature '(prevState: undefined): undefined’.ts(2345)
これらのErrorの原因はconst [sound, setSound] = React.useState();でした。
If you do the following the error disappears. (以下のようにすると、エラーは消えます。)
const [sound, setSound] = useState<any>()
修正後のコード
import * as React from 'react';
import { Text, View, StyleSheet, Button } from 'react-native';
import { Audio } from 'expo-av';
export default function App() {
//const [sound, setSound] = React.useState();
const [sound, setSound] = useState<any>();
async function playSound() {
console.log('Loading Sound');
const { sound } = await Audio.Sound.createAsync(
// eslint-disable-next-line @typescript-eslint/no-var-requires
require('./assets/Hello.mp3')
);
setSound(sound);
console.log('Playing Sound');
await sound.playAsync();
}
React.useEffect(() => {
return sound
? () => {
console.log('Unloading Sound');
sound.unloadAsync(); }
: undefined;
}, [sound]);
return (
<View>
<Button title="Play Sound" onPress={playSound} />
</View>
);
}
なお、コードが正しくても、iphoneのシミュレータで音が出ない時があります。expoのiphoneのアプリから実行すると、音が出るので正しいかどうか確認できます。
めでたし、めでたし。(Happily ever after)