feat: 全面清理类型错误 — tsc 零错误,any 标注全部消除

- 修复所有 33 个原始 tsc 编译错误(ink JSX 声明、类型不匹配、null check 等)
- 清理 176 处 `: any` 类型标注,全部替换为具体推断类型
- 修复清理过程中引入的 41 个回归错误
- 最终结果:0 tsc 错误,0 个非注释 any 标注
- Build 验证通过(25.75MB bundle)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
claude-code-best
2026-04-01 01:00:10 +08:00
parent 58f1bd49cb
commit fac9341e73
129 changed files with 555 additions and 252 deletions

View File

@@ -334,22 +334,22 @@ export async function generateSuggestion(
const firstAssistantMsg = result.messages.find(m => m.type === 'assistant')
const generationRequestId =
firstAssistantMsg?.type === 'assistant'
? (firstAssistantMsg.requestId ?? null)
? ((firstAssistantMsg.requestId as string) ?? null)
: null
for (const msg of result.messages) {
if (msg.type !== 'assistant') continue
const contentArr = Array.isArray(msg.message.content) ? msg.message.content : []
const contentArr = Array.isArray(msg.message.content) ? msg.message.content as Array<{ type: string; text?: string }> : []
const textBlock = contentArr.find(b => b.type === 'text')
if (textBlock?.type === 'text') {
if (textBlock?.type === 'text' && typeof textBlock.text === 'string') {
const suggestion = textBlock.text.trim()
if (suggestion) {
return { suggestion: textBlock.text.trim() as string, generationRequestId }
return { suggestion, generationRequestId }
}
}
}
return { suggestion: null as string | null, generationRequestId }
return { suggestion: null as (string | null), generationRequestId }
}
export function shouldFilterSuggestion(

View File

@@ -2079,7 +2079,7 @@ async function* queryModel(
})
throw new Error('Content block is not a connector_text block')
}
contentBlock.connector_text += delta.connector_text
;(contentBlock as { connector_text: string }).connector_text += delta.connector_text
} else {
switch (delta.type) {
case 'citations_delta':
@@ -2123,7 +2123,7 @@ async function* queryModel(
})
throw new Error('Content block is not a text block')
}
contentBlock.text += delta.text
;(contentBlock as { text: string }).text += delta.text
break
case 'signature_delta':
if (
@@ -2158,7 +2158,7 @@ async function* queryModel(
})
throw new Error('Content block is not a thinking block')
}
contentBlock.thinking += delta.thinking
;(contentBlock as { thinking: string }).thinking += delta.thinking
break
}
}

View File

@@ -159,7 +159,7 @@ export async function getAnthropicClient({
? process.env.ANTHROPIC_SMALL_FAST_MODEL_AWS_REGION
: getAWSRegion()
const bedrockArgs: any = {
const bedrockArgs: Record<string, unknown> = {
...ARGS,
awsRegion,
...(isEnvTruthy(process.env.CLAUDE_CODE_SKIP_BEDROCK_AUTH) && {
@@ -173,7 +173,7 @@ export async function getAnthropicClient({
bedrockArgs.skipAuth = true
// Add the Bearer token for Bedrock API key authentication
bedrockArgs.defaultHeaders = {
...bedrockArgs.defaultHeaders,
...(bedrockArgs.defaultHeaders as Record<string, string> | undefined),
Authorization: `Bearer ${process.env.AWS_BEARER_TOKEN_BEDROCK}`,
}
} else if (!isEnvTruthy(process.env.CLAUDE_CODE_SKIP_BEDROCK_AUTH)) {

View File

@@ -459,7 +459,7 @@ export async function checkResponseForCacheBreak(
// assistant message timestamp in the messages array (before the current response)
const lastAssistantMessage = messages.findLast(m => m.type === 'assistant')
const timeSinceLastAssistantMsg = lastAssistantMessage
? Date.now() - new Date(lastAssistantMessage.timestamp).getTime()
? Date.now() - new Date(lastAssistantMessage.timestamp as string | number).getTime()
: null
// Skip the first call — no previous value to compare against

View File

@@ -232,7 +232,7 @@ export async function getSessionLogs(
// Update our lastUuid to the last entry's UUID
const lastEntry = logs.at(-1)
if (lastEntry && 'uuid' in lastEntry && lastEntry.uuid) {
lastUuidMap.set(sessionId, lastEntry.uuid as string)
lastUuidMap.set(sessionId, lastEntry.uuid as UUID)
}
}

View File

@@ -1,2 +1,2 @@
// Auto-generated type stub — replace with real implementation
export type isConnectorTextBlock = any;
export type isConnectorTextBlock = (block: unknown) => boolean;

View File

@@ -1,4 +1,4 @@
// Auto-generated type stub — replace with real implementation
export type EffortValue = any;
export type modelSupportsEffort = any;
export type EffortLevel = any;
export type EffortValue = 'low' | 'medium' | 'high' | 'max' | number;
export type modelSupportsEffort = (model: string) => boolean;
export type EffortLevel = 'low' | 'medium' | 'high' | 'max';

View File

@@ -1,3 +1,3 @@
// Auto-generated stub — replace with real implementation
export {};
export const getCachedMCConfig: any = (() => {}) as any;
export const getCachedMCConfig: () => { enabled?: boolean; systemPromptSuggestSummaries?: boolean; supportedModels?: string[]; [key: string]: unknown } = () => ({});

View File

@@ -1,8 +1,22 @@
// Auto-generated stub — replace with real implementation
export {};
export const isReactiveOnlyMode: any = (() => {}) as any;
export const reactiveCompactOnPromptTooLong: any = (() => {}) as any;
export const isReactiveCompactEnabled: any = (() => {}) as any;
export const isWithheldPromptTooLong: any = (() => {}) as any;
export const isWithheldMediaSizeError: any = (() => {}) as any;
export const tryReactiveCompact: any = (() => {}) as any;
import type { Message } from 'src/types/message';
import type { CompactionResult } from './compact.js';
export const isReactiveOnlyMode: () => boolean = () => false;
export const reactiveCompactOnPromptTooLong: (
messages: Message[],
cacheSafeParams: Record<string, unknown>,
options: { customInstructions?: string; trigger?: string },
) => Promise<{ ok: boolean; reason?: string; result?: CompactionResult }> = async () => ({ ok: false });
export const isReactiveCompactEnabled: () => boolean = () => false;
export const isWithheldPromptTooLong: (message: Message) => boolean = () => false;
export const isWithheldMediaSizeError: (message: Message) => boolean = () => false;
export const tryReactiveCompact: (params: {
hasAttempted: boolean;
querySource: string;
aborted: boolean;
messages: Message[];
cacheSafeParams: Record<string, unknown>;
}) => Promise<CompactionResult | null> = async () => null;

View File

@@ -1,7 +1,17 @@
// Auto-generated stub — replace with real implementation
export {};
export const isSnipMarkerMessage: any = (() => {}) as any;
export const snipCompactIfNeeded: any = (() => {}) as any;
export const isSnipRuntimeEnabled: any = (() => {}) as any;
export const shouldNudgeForSnips: any = (() => {}) as any;
export const SNIP_NUDGE_TEXT: any = (() => {}) as any;
import type { Message } from 'src/types/message';
export const isSnipMarkerMessage: (message: Message) => boolean = () => false;
export const snipCompactIfNeeded: (
messages: Message[],
options?: { force?: boolean },
) => { messages: Message[]; executed: boolean; tokensFreed: number; boundaryMessage?: Message } = (messages) => ({
messages,
executed: false,
tokensFreed: 0,
});
export const isSnipRuntimeEnabled: () => boolean = () => false;
export const shouldNudgeForSnips: (messages: Message[]) => boolean = () => false;
export const SNIP_NUDGE_TEXT: string = '';

View File

@@ -1,4 +1,7 @@
// Auto-generated stub — replace with real implementation
export {};
export const isSnipBoundaryMessage: any = (() => {}) as any;
export const projectSnippedView: any = (() => {}) as any;
import type { Message } from 'src/types/message';
export const isSnipBoundaryMessage: (message: Message) => boolean = () => false;
export const projectSnippedView: (messages: Message[]) => Message[] = (messages) => messages;

View File

@@ -1,10 +1,66 @@
// Auto-generated stub — replace with real implementation
export {};
export const getStats: any = (() => {}) as any;
export const isContextCollapseEnabled: any = (() => {}) as any;
export const subscribe: any = (() => {}) as any;
export const applyCollapsesIfNeeded: any = (() => {}) as any;
export const isWithheldPromptTooLong: any = (() => {}) as any;
export const recoverFromOverflow: any = (() => {}) as any;
export const resetContextCollapse: any = (() => {}) as any;
export const initContextCollapse: any = (() => {}) as any;
import type { Message } from '../../types/message.js'
import type { ToolUseContext } from '../../Tool.js'
import type { QuerySource } from '../../constants/querySource.js'
export interface ContextCollapseHealth {
totalSpawns: number
totalErrors: number
lastError: string | null
emptySpawnWarningEmitted: boolean
totalEmptySpawns: number
}
export interface ContextCollapseStats {
collapsedSpans: number
collapsedMessages: number
stagedSpans: number
health: ContextCollapseHealth
}
export interface CollapseResult {
messages: Message[]
}
export interface DrainResult {
committed: number
messages: Message[]
}
export const getStats: () => ContextCollapseStats = (() => ({
collapsedSpans: 0,
collapsedMessages: 0,
stagedSpans: 0,
health: {
totalSpawns: 0,
totalErrors: 0,
lastError: null,
emptySpawnWarningEmitted: false,
totalEmptySpawns: 0,
},
}));
export const isContextCollapseEnabled: () => boolean = (() => false);
export const subscribe: (callback: () => void) => () => void = ((_callback: () => void) => () => {});
export const applyCollapsesIfNeeded: (
messages: Message[],
toolUseContext: ToolUseContext,
querySource: QuerySource,
) => Promise<CollapseResult> = (async (messages: Message[]) => ({ messages }));
export const isWithheldPromptTooLong: (
message: Message,
isPromptTooLongMessage: (msg: Message) => boolean,
querySource: QuerySource,
) => boolean = (() => false);
export const recoverFromOverflow: (
messages: Message[],
querySource: QuerySource,
) => DrainResult = ((messages: Message[]) => ({ committed: 0, messages }));
export const resetContextCollapse: () => void = (() => {});
export const initContextCollapse: () => void = (() => {});

View File

@@ -1,3 +1,4 @@
// Auto-generated stub — replace with real implementation
export {};
export const projectView: any = (() => {}) as any;
import type { Message } from 'src/types/message.js';
export const projectView: (messages: Message[]) => Message[] = (messages) => messages;

View File

@@ -1,3 +1,3 @@
// Auto-generated stub — replace with real implementation
export {};
export const restoreFromEntries: any = (() => {}) as any;
export const restoreFromEntries: (...args: unknown[]) => void = () => {};

View File

@@ -273,7 +273,7 @@ function extractWrittenPaths(agentMessages: Message[]): string[] {
// ============================================================================
type AppendSystemMessageFn = (
msg: Exclude<SystemMessage, SystemLocalCommandMessage>,
msg: SystemMessage,
) => void
/** The active extractor function, set by initExtractMemories(). */

View File

@@ -1,4 +1,6 @@
// Auto-generated stub — replace with real implementation
import type { Message } from '../../types/message.js';
export {};
export const writeSessionTranscriptSegment: any = (() => {}) as any;
export const flushOnDateChange: any = (() => {}) as any;
export const writeSessionTranscriptSegment: (messages: Message[]) => void = (() => {});
export const flushOnDateChange: (messages: Message[], currentDate: string) => void = (() => {});

View File

@@ -1,3 +1,3 @@
// Auto-generated stub — replace with real implementation
export {};
export const isSkillSearchEnabled: any = (() => {}) as any;
export const isSkillSearchEnabled: () => boolean = () => false;

View File

@@ -1,3 +1,3 @@
// Auto-generated stub — replace with real implementation
export {};
export const clearSkillIndexCache: any = (() => {}) as any;
export const clearSkillIndexCache: () => void = () => {};

View File

@@ -1,5 +1,18 @@
// Auto-generated stub — replace with real implementation
export {};
export const startSkillDiscoveryPrefetch: any = (() => {}) as any;
export const collectSkillDiscoveryPrefetch: any = (() => {}) as any;
export const getTurnZeroSkillDiscovery: any = (() => {}) as any;
import type { Attachment } from '../../utils/attachments.js'
import type { Message } from '../../types/message.js'
import type { ToolUseContext } from '../../Tool.js'
export const startSkillDiscoveryPrefetch: (
input: string | null,
messages: Message[],
toolUseContext: ToolUseContext,
) => Promise<Attachment[]> = (async () => []);
export const collectSkillDiscoveryPrefetch: (
pending: Promise<Attachment[]>,
) => Promise<Attachment[]> = (async (pending) => pending);
export const getTurnZeroSkillDiscovery: (
input: string,
messages: Message[],
context: ToolUseContext,
) => Promise<Attachment | null> = (async () => null);