fix(vscode-ide-companion): improve type safety in webview components

修复 webview 组件的类型安全问题:
- App.tsx: 规范化工具调用状态为联合类型
- InProgressToolCall.tsx: 安全处理非字符串类型的 title 属性
- InputForm.tsx: 修正 RefObject 泛型类型声明
- ReadToolCall.tsx: 添加空 children 避免 ToolCallContainer 警告
This commit is contained in:
yiliang114
2025-11-24 20:33:27 +08:00
parent b6914c6b33
commit 795e7fa2c5
4 changed files with 26 additions and 6 deletions

View File

@@ -24,7 +24,7 @@ import {
import { useCompletionTrigger } from './hooks/useCompletionTrigger.js';
import { SaveSessionDialog } from './components/SaveSessionDialog.js';
import { InfoBanner } from './components/InfoBanner.js';
import { ChatHeader } from './components/ui/ChatHeader.js';
import { ChatHeader } from './components/layouts/ChatHeader.js';
import {
UserMessage,
AssistantMessage,
@@ -830,12 +830,22 @@ export const App: React.FC = () => {
}
}
// Normalize status to our union type
const normalizedStatus = (
permToolCall.status === 'pending' ||
permToolCall.status === 'in_progress' ||
permToolCall.status === 'completed' ||
permToolCall.status === 'failed'
? permToolCall.status
: 'pending'
) as ToolCallUpdate['status'];
handleToolCallUpdate({
type: 'tool_call',
toolCallId: permToolCall.toolCallId,
kind,
title: permToolCall.title,
status: permToolCall.status || 'pending',
status: normalizedStatus,
content: permToolCall.content as Array<{
type: 'content' | 'diff';
content?: {

View File

@@ -68,6 +68,12 @@ export const InProgressToolCall: React.FC<InProgressToolCallProps> = ({
// Get status text
const statusText = getStatusText(status || 'in_progress');
// Safely prepare a display value for title. Titles may sometimes arrive as
// non-string objects; ensure we render a string in that case.
const titleText = typeof title === 'string' ? title : undefined;
const titleDisplay: React.ReactNode =
typeof title === 'string' ? title : title ? JSON.stringify(title) : null;
return (
<div className="in-progress-tool-call">
<div className="in-progress-tool-call-header">
@@ -79,8 +85,8 @@ export const InProgressToolCall: React.FC<InProgressToolCallProps> = ({
</span>
</div>
{title && title !== kindLabel && (
<div className="in-progress-tool-call-title">{title}</div>
{titleDisplay && (titleText ? titleText !== kindLabel : true) && (
<div className="in-progress-tool-call-title">{titleDisplay}</div>
)}
{locations && locations.length > 0 && (

View File

@@ -10,7 +10,9 @@ type EditMode = 'ask' | 'auto' | 'plan';
interface InputFormProps {
inputText: string;
inputFieldRef: React.RefObject<HTMLDivElement | null>;
// Note: RefObject<T> carries nullability in its `current` property, so the
// generic should be `HTMLDivElement` (not `HTMLDivElement | null`).
inputFieldRef: React.RefObject<HTMLDivElement>;
isStreaming: boolean;
isComposing: boolean;
editMode: EditMode;

View File

@@ -48,7 +48,9 @@ export const ReadToolCall: React.FC<BaseToolCallProps> = ({ toolCall }) => {
label={`Read ${fileName}`}
status="success"
toolCallId={toolCallId}
/>
>
{null}
</ToolCallContainer>
);
}