تايب سكريبت - خطأ عند محاولة الوصول إلى خاصية الخطأ في AVPlaybackStatus


أنا جديد في TypeScript وأحاول العمل مع expo-av لتشغيل الصوت.

يعطيني الكود التالي خطأ: TS2339: الخاصية 'error' غير موجودة في النوع 'AVPlaybackStatus'.

const { sound, status } = await Audio.Sound.createAsync(track.mp3);
if (status.isLoaded) {
  console.info(status.durationMillis);
}
else {
  console.error("track not loaded", status.error);
}

نظرت في تعريف status ووجدت:

export type AVPlaybackStatus =
  | {
      isLoaded: false;
      androidImplementation?: string;
      error?: string; // populated exactly once when an error forces the object to unload
    }
  | {
      isLoaded: true;
      androidImplementation?: string;

      uri: string;

      progressUpdateIntervalMillis: number;
      durationMillis?: number;
      positionMillis: number;
      playableDurationMillis?: number;
      seekMillisToleranceBefore?: number;
      seekMillisToleranceAfter?: number;

      shouldPlay: boolean;
      isPlaying: boolean;
      isBuffering: boolean;

      rate: number;
      shouldCorrectPitch: boolean;
      volume: number;
      isMuted: boolean;
      isLooping: boolean;

      didJustFinish: boolean; // true exactly once when the track plays to finish
    };

لم أر هذا البناء من قبل ولكنني أخمن أن هذا نوع اتحاد أو تقاطع (?)

كيف يمكنني الوصول إلى status.error؟ وما هو التعبير الشائع/البناء النموذجي للعمل مع مثل هذه الأنواع؟

الإجابة رقم 1

النمط هو الاتحاد التمييزي (docs)، حيث يمكن لـ TypeScript تحديد النوع بدقة بناءً على حقل واحد يكون مميزًا لكل من البدائل. في هذه الحالة، هو الحقل المنطقي isLoaded، ولكن لكي يعمل ذلك، تحتاج إلى تمكين strictNullChecks. بخلاف ذلك، فإن الطريقة التي تتعامل بها معه صحيحة تمامًا.

الإجابة رقم 2

حل واحد معقد سيكون هذا:

sound.setOnPlaybackStatusUpdate(status => {
  if ("didJustFinish" in status && status.didJustFinish) {
    console.log("Finished playing");
  }
});