-
Notifications
You must be signed in to change notification settings - Fork 2
Open
Description
我已梳理并分批修正类型,先列出范围与结果,再给出每处的 A/B 方案与取舍说明。
若你要我继续把 Studio 示例里残留的 any 也全部收敛,我可以继续推进。
总体结果
- 目标优先级:组件边界 > 外部数据入口 > 工具函数 > 错误处理 > 其他
- 已移除/替换的 any:shared 工具、compositions 包类型与大量纸张背景组件、web
页面与预览、Studio 配置/设计系统、部分脚本与错误处理
- 未动的文件:生成文件(apps/web/src/routeTree.gen.ts),以及较大 Demo/3D/图
表示例里局部 any(标注为“延期项”)
关键改动(文件级)
- 工具库(安全、无语义变更)
- packages/shared/src/theme/utils.ts:1
- pick 改为基于 unknown 的 Record 收敛;所有 API 改为 unknown + 收
窄;normalize/derive/make 维持返回结构不变。
- 公共类型边界(兼容增强)
- packages/compositions/src/types.ts:1
- CompositionDefinition 改为泛型 P extends Record<string, unknown>,
默认 Record<string, unknown>,component: ComponentType<P>,
defaultProps: P
- apps/web/src/compositions/types.ts:1
- RemotionCompositionDefinition 同 CompositionDefinition 处理
- Web 页面与预览(移除 any/catch)
- apps/web/src/routes/compositions-demo.tsx:1
- library: CompositionDefinition[];form: Record<string, unknown>;
移除 as any;主题字段通过 getThemeFrom 收敛;Player 的 component/
inputProps 不再 any。
- apps/web/src/components/editor/EditorPreviewPanel.tsx:1
- playerComponent: ComponentType<Record<string, unknown>>;
inputProps 明确为 Record<string, unknown>
- apps/web/src/routes/__root.tsx:1
- wheel 事件 removeEventListener 移除 as any,使用常量 wheelOptions
- apps/web/src/polyfill.ts:1
- File polyfill 改为 unknown 双重断言,避免 any
- apps/web/src/routes/mcp.ts:1
- inputSchema 使用 z.object(...),去掉 as any
- apps/web/src/lib/render-bridge.ts:1
- catch(e: unknown)
- apps/web/src/lib/studio-bundle.ts:1
- config/chConfig 使用最小 Webpack-like 类型与 unknown,移除 any
- Studio 设计系统与配置(移除 any)
- apps/studio/src/design-system/index.ts:1
- utils.getColor 安全取值;responsive<T> 泛型;mergeStyles 使
用 CSSProperties
- apps/studio/src/design-system/tokens/spacing.ts:1
- getComponentSpacing 去除 as any,返回 unknown 或原对象
- apps/studio/src/design-system/layout/positioning.ts:1
- flex.row/column 的 align 参数使用 CSSProperties["alignItems"],移
除 as any
- apps/studio/remotion.config.ts:1
- 与 web 一致的 WebpackLikeConfig + unknown,移除 any
- Studio 类型与注册(边界更稳)
- apps/studio/src/types.ts:1
- ClipMetadata.defaultProps: Record<string, unknown>;schema:
unknown
- apps/studio/src/types/slideComposition.ts:1
- 移除 props/组件 any,统一为 Record<string, unknown>;补齐常用属性
而不设 any 索引;SlideElementProps.clipComponent 使用受限类型
- apps/studio/src/lib/clip-registry.ts:1
- defaultProps 断言为 Record<string, unknown>
- apps/studio/src/utils/clipRegistry.ts:252
- (clip as { defaultProps?: Record<string,
unknown> }).defaultProps,替换 as any
- compositions 纸张背景类组件(全面移除 any)
- 所有 paper-*.tsx(如 paper-warp/paper-smoke-ring/... 共 20+)
- props 统一为 { fit?: string } & Record<string, unknown>;展开
props;fit 以 typeof props.fit === 'string' 收敛;去掉 ...(props
as any)、fit as any
- compositions 其他组件/定义
- image-primitive/component.tsx:44
- objectPosition 使用 React.CSSProperties["objectPosition"]
- image-primitive/definition.ts:12、code-primitive/definition.ts:12、
text-primitive/definition.ts:12、group-primitive/definition.ts:12、
rectangle-primitive/definition.ts:12
- defaultProps 使用 Partial<typeof defaults> 替代 as any
- text-primitive/component.tsx:42,46
- 去除 fontWeight/textAlign 的 any
- editor/editor-canvas-export/component.tsx:17-55
- computeTransform 直接使用 item;组合定义/组件使用
CompositionDefinition 与 ComponentType<Record<string, unknown>>;
compositionProps 安全展开,移除多处 any
- packages/compositions/src/compositions/library/code-animation/theme-
registry.ts:5
- highlight?: unknown
- 主题注册(web)
- apps/web/src/compositions/library/code-animation/theme-registry.ts:4
- highlight?: unknown
- 错误处理
- scripts/test-remotion-bundle.ts / scripts/build-thumbnail.ts / apps/
web/src/lib/render-bridge.ts / Studio 字幕组件等
- catch(e: unknown),并保留原日志语义
- Studio 音频可视化
- apps/studio/src/composition/captions/audiowave/component.tsx
- (window as any) 改为 window as unknown as { Audio,
AudioContext },移除 any
已保留不动(生成或大示例,延期项)
- apps/web/src/routeTree.gen.ts: 生成文件(注释已说明不可修改)。
- 三维/图表/大型模板中与三方库紧耦合的 any(如 gsap/THREE/Intl 的快速
断言):
- apps/studio/src/projects/P080-llm-cheat/...(大量 THREE.Material 相
关)
- apps/studio/src/scenes-templates/...(gsap.utils 与自定义节点数
据 any)
- apps/studio/src/composition/text-animation/rotating-
text(Intl.Segmenter)
- 如需继续,我可以以 wrapper/最小 d.ts 补丁方式逐步替换。
— — —
工作流与审阅清单
1. 审阅(Review)
- 显式 any(原因)
- 组件 props/ComponentType<any>:历史默认宽松,便于动态渲染。
- 工具函数参数/返回 any:图省事,类型信息缺失(如 theme utils)。
- Webpack 覆盖 config: any:第三方类型复杂/未引入类型。
- 运行时 env/浏览器 API:window/Audio/Intl 等未按环境分型。
- 生成代码:路由树生成器使用 as any(工具生成限制)。
- 隐式 any(原因)
- catch(e) 未设 unknown:tsconfig 未强制 useUnknownInCatchVariables。
- Map/Record 异构访问:reduce 链式取值未做守卫。
- 风险标注
- 组件边界:高(跨包/渲染器传 props)。
- 工具函数:中(被多处调用)。
- 第三方类型缺失:中(Webpack/CodeHike/Audio)。
- 错误处理:低(已标准化 unknown)。
2. 分组(Attribution)
- 来源数据:主题 JSON、Studio 项目数据(EditorItem/Clip metadata)
- 组件边界:CompositionDefinition、RemotionCompositionDefinition、纸张背景组
件 props
- 工具函数:shared/theme/utils.ts、design-system utils
- 第三方库:Webpack 配置、codehike/mdx、window.Audio/AudioContext、
Intl.Segmenter、THREE、gsap
- 错误处理:各处 catch(e)
3. 方案(A/B)
- 组件边界(CompositionDefinition 与组件 props)
- A:CompositionDefinition 引入泛型 P 默认 Record<string, unknown>;组件
统一 ComponentType<P>;defaultProps:P
- 优点:与现有调用点兼容,推断稳定;无运行时变化。
- 缺点:个别地方需要补 Partial<...> 帮助推断。
- B:为每个组件定义精确 Props 类型并在导出 Definition 时强约束
- 优点:最强约束与提示;缺点:工程量大,易受变更影响。
- 取舍:A(已实施),部分 Definition 用 Partial<defaults> 兜底推断。
- 工具函数(theme utils)
- A:unknown + 收窄(isRecord + pick),返回保持原结构
- 优点:安全,调用方无需改动。
- B:显式主题 JSON 类型(详尽结构)
- 优点:强类型;缺点:维护成本高。
- 取舍:A(已实施)。
- Webpack/CodeHike 配置
- A:最小 WebpackLikeConfig + unknown,并按使用位置做窄化
- B:引入 @types/webpack 或完整 bundler 类型
- 取舍:A(已实施),保持零依赖。
- 运行时 API(window.Audio/AudioContext)
- A:unknown -> 结构断言对象 { Audio, AudioContext }
- B:ambient d.ts 声明全局
- 取舍:A(已实施),不污染全局类型。
- 错误处理
- A:catch(e: unknown) + 原样日志/传递
- B:自定义 AppError 类型并转换
- 取舍:A(已实施),保持语义不变。
4. 取舍(Decision)
- 已全面采用 A 案(unknown + 收窄、泛型与约束)以最小风险替代 any,运行时语
义不变,外部 API 兼容不破坏。
- 分步策略:已将高优先级(跨包类型/工具/错误处理/页面)收敛;Studio 大型示例
与三方对象流转(THREE/gsap/Intl)列为后续阶段。
Metadata
Metadata
Assignees
Labels
No labels