From 47293de3acda3338ff7a6eda3872b608ec511de9 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 11 Jul 2026 19:38:43 +0000 Subject: [PATCH] Add moduleSuffixes to tsconfig Resolve platform-specific modules native-first ([".ios", ".android", ".native", ""]) during typechecking, matching the react-native customConditions already set by the base config. Typecheck now sees the .native variants of web-only modules, so their throw-stubs gain real signatures (typed props, never return, error class exports) to keep their web consumers typechecking correctly. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01BCuMKXWHuyGoNhTVAHBMyk --- .../VideoEmbedInnerWeb.native.tsx | 22 ++++++++++++++++++- .../web-controls/VideoControls.native.tsx | 18 ++++++++++++++- .../hooks/useWelcomeModal.native.ts | 6 ++++- src/lib/hotkeys/index.native.tsx | 2 +- .../videos/SubtitleFilePicker.native.tsx | 5 ++++- tsconfig.json | 1 + 6 files changed, 49 insertions(+), 5 deletions(-) diff --git a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoEmbedInnerWeb.native.tsx b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoEmbedInnerWeb.native.tsx index 8664aae142..71b3533d03 100644 --- a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoEmbedInnerWeb.native.tsx +++ b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoEmbedInnerWeb.native.tsx @@ -1,3 +1,23 @@ -export function VideoEmbedInnerWeb() { +import {type AppBskyEmbedVideo} from '@atproto/api' + +export function VideoEmbedInnerWeb(_props: { + embed: AppBskyEmbedVideo.View + active: boolean + setActive: () => void + onScreen: boolean + lastKnownTime: React.RefObject +}): never { throw new Error('VideoEmbedInnerWeb may not be used on native.') } + +export class HLSUnsupportedError extends Error { + constructor() { + super('HLS is not supported') + } +} + +export class VideoNotFoundError extends Error { + constructor() { + super('Video not found') + } +} diff --git a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/VideoControls.native.tsx b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/VideoControls.native.tsx index e2e24ed367..0088c186ab 100644 --- a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/VideoControls.native.tsx +++ b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/VideoControls.native.tsx @@ -1,3 +1,19 @@ -export function Controls() { +import type Hls from 'hls.js' + +export function Controls(_props: { + videoRef: React.RefObject + hlsRef: React.RefObject + active: boolean + setActive: () => void + focused: boolean + setFocused: (focused: boolean) => void + onScreen: boolean + fullscreenRef: React.RefObject + hlsLoading: boolean + hasSubtitleTrack: boolean + isGif: boolean + altText?: string + updateCuePositions: (controlsVisible?: boolean) => void +}): never { throw new Error('VideoWebControls may not be used on native.') } diff --git a/src/components/hooks/useWelcomeModal.native.ts b/src/components/hooks/useWelcomeModal.native.ts index f5bc1aa4ed..ec581d5410 100644 --- a/src/components/hooks/useWelcomeModal.native.ts +++ b/src/components/hooks/useWelcomeModal.native.ts @@ -1,3 +1,7 @@ -export function useWelcomeModal() { +export function useWelcomeModal(): { + isOpen: boolean + open: () => void + close: () => void +} { throw new Error('useWelcomeModal is web only') } diff --git a/src/lib/hotkeys/index.native.tsx b/src/lib/hotkeys/index.native.tsx index a0fe0e105a..58bfb1fef8 100644 --- a/src/lib/hotkeys/index.native.tsx +++ b/src/lib/hotkeys/index.native.tsx @@ -4,7 +4,7 @@ export function Provider({children}: {children: React.ReactNode}) { return children } -const noop = () => {} +const noop = (_scope: string) => {} export function useHotkeysContext() { return useMemo( diff --git a/src/view/com/composer/videos/SubtitleFilePicker.native.tsx b/src/view/com/composer/videos/SubtitleFilePicker.native.tsx index f2b9a7b04a..a31e23c22a 100644 --- a/src/view/com/composer/videos/SubtitleFilePicker.native.tsx +++ b/src/view/com/composer/videos/SubtitleFilePicker.native.tsx @@ -1,3 +1,6 @@ -export function SubtitleFilePicker() { +export function SubtitleFilePicker(_props: { + onSelectFile: (file: File) => void + disabled?: boolean +}): never { throw new Error('SubtitleFilePicker is a web-only component') } diff --git a/tsconfig.json b/tsconfig.json index c3f559d917..2f69ed70af 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,6 +3,7 @@ "compilerOptions": { "jsx": "react-jsx", "module": "esnext", + "moduleSuffixes": [".ios", ".android", ".native", ""], "lib": ["dom", "esnext"], "types": ["node", "jest"], "paths": {