Fixed TypeScript and ESLint errors properly without any or ignores

This commit is contained in:
mkorwel
2026-04-17 16:00:16 +00:00
parent 18369c0366
commit a1d4604131
17 changed files with 143 additions and 72 deletions
+8 -9
View File
@@ -55,8 +55,14 @@ export default tseslint.config(
'**/node_modules/**',
'eslint.config.js',
'packages/**/dist/**',
'packages/*/src/**/*.js',
'packages/*/src/**/*.js.map',
'packages/**/*.js',
'packages/**/*.js.map',
'integration-tests/**/*.js',
'integration-tests/**/*.js.map',
'memory-tests/**/*.js',
'memory-tests/**/*.js.map',
'perf-tests/**/*.js',
'perf-tests/**/*.js.map',
'bundle/**',
'package/bundle/**',
'.integration-tests/**',
@@ -294,7 +300,6 @@ export default tseslint.config(
'vitest/expect-expect': 'off',
'vitest/no-commented-out-tests': 'off',
'no-restricted-syntax': ['error', ...commonRestrictedSyntaxRules],
'@typescript-eslint/no-explicit-any': 'off',
},
},
{
@@ -412,12 +417,6 @@ export default tseslint.config(
'@typescript-eslint/no-require-imports': 'off',
},
},
{
files: ['integration-tests/**/*.ts', 'memory-tests/**/*.ts', 'perf-tests/**/*.ts'],
rules: {
'@typescript-eslint/no-explicit-any': 'off',
},
},
// Prettier config must be last
prettierConfig,
// extra settings for scripts that we run directly with node
+3 -1
View File
@@ -39,7 +39,9 @@ describe('web-fetch rate limiting', () => {
const rateLimitedCalls = toolLogs.filter(
(log) =>
log.toolRequest.name === 'web_fetch' &&
(log.toolRequest as any).error?.includes('Rate limit exceeded'),
(log.toolRequest as { error?: string }).error?.includes(
'Rate limit exceeded',
),
);
expect(rateLimitedCalls.length).toBeGreaterThan(0);
+5 -5
View File
@@ -108,7 +108,7 @@ describe('Plan Mode', () => {
).toBeDefined();
expect(
planWrite?.toolRequest.success,
`Expected write_file to succeed, but it failed with error: ${(planWrite?.toolRequest as any).error}`,
`Expected write_file to succeed, but it failed with error: ${(planWrite?.toolRequest as { error?: string }).error}`,
).toBe(true);
});
@@ -221,7 +221,7 @@ describe('Plan Mode', () => {
).toBeDefined();
expect(
planWrite?.toolRequest.success,
`Expected write_file to succeed, but it failed with error: ${(planWrite?.toolRequest as any).error}`,
`Expected write_file to succeed, but it failed with error: ${(planWrite?.toolRequest as { error?: string }).error}`,
).toBe(true);
});
it('should switch from a pro model to a flash model after exiting plan mode', async () => {
@@ -271,14 +271,14 @@ describe('Plan Mode', () => {
const apiRequests = rig.readAllApiRequest();
const modelNames = apiRequests.map(
(r) => (r.attributes as any)?.model || 'unknown',
(r) => (r.attributes as { model?: string })?.model || 'unknown',
);
const proRequests = apiRequests.filter((r) =>
(r.attributes as any)?.model?.includes('pro'),
(r.attributes as { model?: string })?.model?.includes('pro'),
);
const flashRequests = apiRequests.filter((r) =>
(r.attributes as any)?.model?.includes('flash'),
(r.attributes as { model?: string })?.model?.includes('flash'),
);
expect(
@@ -116,8 +116,8 @@ expect.extend({
// Extend Vitest's `expect` interface with the custom matcher's type definition.
declare module 'vitest' {
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-empty-object-type
interface Assertion<T = any> extends CustomMatchers<T> {}
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
interface Assertion<T> extends CustomMatchers<T> {}
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
interface AsymmetricMatchersContaining extends CustomMatchers {}
+1 -2
View File
@@ -42,8 +42,7 @@ import {
type OverflowState,
} from '../ui/contexts/OverflowContext.js';
import { makeFakeConfig } from '../../../../packages/core/src/test-utils/config.js';
import { type Config } from '@google/gemini-cli-core';
import { makeFakeConfig, type Config } from '@google/gemini-cli-core';
import { FakePersistentState } from './persistentStateFake.js';
import { AppContext, type AppState } from '../ui/contexts/AppContext.js';
import { createMockSettings } from './settings.js';
+22 -12
View File
@@ -40,6 +40,7 @@ import {
type AgentDefinition,
CoreToolCallStatus,
IdeClient,
MCPDiscoveryState,
} from '@google/gemini-cli-core';
// Mock coreEvents
@@ -363,22 +364,22 @@ describe('AppContainer State Management Brand New', () => {
class ErrorBoundary extends Component<
{ children: ReactNode },
{ hasError: boolean; error: any }
{ hasError: boolean; error: unknown }
> {
constructor(props: any) {
constructor(props: { children: ReactNode }) {
super(props);
this.state = { hasError: false, error: null };
}
static getDerivedStateFromError(error: any) {
static getDerivedStateFromError(error: unknown) {
return { hasError: true, error };
}
override componentDidCatch(error: any, errorInfo: any) {
override componentDidCatch(error: unknown, errorInfo: unknown) {
// eslint-disable-next-line no-console
console.error('ErrorBoundary caught error:', error, errorInfo);
}
override render() {
if (this.state.hasError) {
return <Text>Error: {this.state.error?.message}</Text>;
return <Text>Error: {(this.state.error as Error)?.message}</Text>;
}
return this.props.children;
}
@@ -451,11 +452,20 @@ describe('AppContainer State Management Brand New', () => {
beforeEach(() => {
persistentStateMock.reset();
vi.clearAllMocks();
(global as any).capturedUIState = null;
(global as any).capturedInputState = null;
(global as any).capturedQuotaState = null;
(global as any).capturedUIActions = null;
(global as any).capturedOverflowActions = null;
(global as typeof global & { capturedUIState: unknown }).capturedUIState =
null;
(
global as typeof global & { capturedInputState: unknown }
).capturedInputState = null;
(
global as typeof global & { capturedQuotaState: unknown }
).capturedQuotaState = null;
(
global as typeof global & { capturedUIActions: unknown }
).capturedUIActions = null;
(
global as typeof global & { capturedOverflowActions: unknown }
).capturedOverflowActions = null;
vi.mocked(useSessionResume).mockReturnValue({
loadHistoryForResume: vi.fn().mockResolvedValue(undefined),
@@ -474,14 +484,14 @@ describe('AppContainer State Management Brand New', () => {
vi.spyOn(useMcpStatusModule, 'useMcpStatus').mockReturnValue({
isMcpReady: true,
discoveryState: 'completed' as any,
discoveryState: MCPDiscoveryState.COMPLETED,
mcpServerCount: 0,
});
vi.spyOn(IdeClient, 'getInstance').mockResolvedValue({
disconnect: vi.fn().mockResolvedValue(undefined),
getCurrentIde: vi.fn().mockReturnValue(null),
} as any);
} as unknown as IdeClient);
// Initialize mock stdout for terminal title tests
@@ -8,10 +8,13 @@ import { describe, it, expect, vi, afterEach, beforeEach } from 'vitest';
import { act } from 'react';
import { renderWithProviders } from '../../test-utils/render.js';
import { createMockSettings } from '../../test-utils/settings.js';
import { makeFakeConfig } from '../../../../core/src/test-utils/config.js';
import { waitFor } from '../../test-utils/async.js';
import { AskUserDialog } from './AskUserDialog.js';
import { QuestionType, type Question } from '@google/gemini-cli-core';
import {
QuestionType,
type Question,
makeFakeConfig,
} from '@google/gemini-cli-core';
import { UIStateContext, type UIState } from '../contexts/UIStateContext.js';
// Helper to write to stdin with proper act() wrapping
@@ -26,7 +26,7 @@ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { SettingsDialog } from './SettingsDialog.js';
import { SettingScope } from '../../config/settings.js';
import { createMockSettings } from '../../test-utils/settings.js';
import { makeFakeConfig } from "@google/gemini-cli-core/src/test-utils/config.js";
import { makeFakeConfig } from '@google/gemini-cli-core';
import { act } from 'react';
import { TEST_ONLY } from '../../utils/settingsUtils.js';
import {
@@ -9,8 +9,8 @@ import { waitFor } from '../../../test-utils/async.js';
import { createMockSettings } from '../../../test-utils/settings.js';
import { ToolResultDisplay } from './ToolResultDisplay.js';
import { describe, it, expect, vi } from 'vitest';
import { makeFakeConfig } from '../../../../../core/src/test-utils/config.js';
import { type AnsiOutput } from '@google/gemini-cli-core';
import { makeFakeConfig } from '@google/gemini-cli-core';
import type { AnsiOutput, Config } from '@google/gemini-cli-core';
describe.sequential('ToolResultDisplay', () => {
beforeEach(() => {
@@ -41,7 +41,9 @@ describe.sequential('ToolResultDisplay', () => {
maxLines={10}
/>,
{
config: makeFakeConfig({ useAlternateBuffer: true }),
config: makeFakeConfig({
useAlternateBuffer: true,
}) as unknown as Config,
settings: createMockSettings({ ui: { useAlternateBuffer: true } }),
},
);
@@ -60,7 +62,9 @@ describe.sequential('ToolResultDisplay', () => {
maxLines={10}
/>,
{
config: makeFakeConfig({ useAlternateBuffer: true }),
config: makeFakeConfig({
useAlternateBuffer: true,
}) as unknown as Config,
settings: createMockSettings({ ui: { useAlternateBuffer: true } }),
},
);
@@ -80,7 +84,9 @@ describe.sequential('ToolResultDisplay', () => {
hasFocus={true}
/>,
{
config: makeFakeConfig({ useAlternateBuffer: true }),
config: makeFakeConfig({
useAlternateBuffer: true,
}) as unknown as Config,
settings: createMockSettings({ ui: { useAlternateBuffer: true } }),
},
);
@@ -94,7 +100,9 @@ describe.sequential('ToolResultDisplay', () => {
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
<ToolResultDisplay resultDisplay="**Some result**" terminalWidth={80} />,
{
config: makeFakeConfig({ useAlternateBuffer: false }),
config: makeFakeConfig({
useAlternateBuffer: false,
}) as unknown as Config,
settings: createMockSettings({ ui: { useAlternateBuffer: false } }),
},
);
@@ -114,7 +122,9 @@ describe.sequential('ToolResultDisplay', () => {
renderOutputAsMarkdown={false}
/>,
{
config: makeFakeConfig({ useAlternateBuffer: false }),
config: makeFakeConfig({
useAlternateBuffer: false,
}) as unknown as Config,
settings: createMockSettings({ ui: { useAlternateBuffer: false } }),
uiState: { constrainHeight: true },
},
@@ -135,7 +145,9 @@ describe.sequential('ToolResultDisplay', () => {
availableTerminalHeight={20}
/>,
{
config: makeFakeConfig({ useAlternateBuffer: false }),
config: makeFakeConfig({
useAlternateBuffer: false,
}) as unknown as Config,
settings: createMockSettings({ ui: { useAlternateBuffer: false } }),
uiState: { constrainHeight: true },
},
@@ -159,7 +171,9 @@ describe.sequential('ToolResultDisplay', () => {
availableTerminalHeight={20}
/>,
{
config: makeFakeConfig({ useAlternateBuffer: false }),
config: makeFakeConfig({
useAlternateBuffer: false,
}) as unknown as Config,
settings: createMockSettings({ ui: { useAlternateBuffer: false } }),
},
);
@@ -193,7 +207,9 @@ describe.sequential('ToolResultDisplay', () => {
availableTerminalHeight={20}
/>,
{
config: makeFakeConfig({ useAlternateBuffer: false }),
config: makeFakeConfig({
useAlternateBuffer: false,
}) as unknown as Config,
settings: createMockSettings({ ui: { useAlternateBuffer: false } }),
},
);
@@ -215,7 +231,9 @@ describe.sequential('ToolResultDisplay', () => {
availableTerminalHeight={20}
/>,
{
config: makeFakeConfig({ useAlternateBuffer: false }),
config: makeFakeConfig({
useAlternateBuffer: false,
}) as unknown as Config,
settings: createMockSettings({ ui: { useAlternateBuffer: false } }),
allowEmptyFrame: true,
},
@@ -237,7 +255,9 @@ describe.sequential('ToolResultDisplay', () => {
renderOutputAsMarkdown={true}
/>,
{
config: makeFakeConfig({ useAlternateBuffer: false }),
config: makeFakeConfig({
useAlternateBuffer: false,
}) as unknown as Config,
settings: createMockSettings({ ui: { useAlternateBuffer: false } }),
uiState: { constrainHeight: true },
},
@@ -257,7 +277,9 @@ describe.sequential('ToolResultDisplay', () => {
renderOutputAsMarkdown={true}
/>,
{
config: makeFakeConfig({ useAlternateBuffer: true }),
config: makeFakeConfig({
useAlternateBuffer: true,
}) as unknown as Config,
settings: createMockSettings({ ui: { useAlternateBuffer: true } }),
},
);
@@ -344,7 +366,9 @@ describe.sequential('ToolResultDisplay', () => {
maxLines={3}
/>,
{
config: makeFakeConfig({ useAlternateBuffer: false }),
config: makeFakeConfig({
useAlternateBuffer: false,
}) as unknown as Config,
settings: createMockSettings({ ui: { useAlternateBuffer: false } }),
uiState: { constrainHeight: true },
},
@@ -384,7 +408,9 @@ describe.sequential('ToolResultDisplay', () => {
availableTerminalHeight={undefined}
/>,
{
config: makeFakeConfig({ useAlternateBuffer: false }),
config: makeFakeConfig({
useAlternateBuffer: false,
}) as unknown as Config,
settings: createMockSettings({ ui: { useAlternateBuffer: false } }),
uiState: { constrainHeight: true },
},
@@ -427,7 +453,9 @@ describe.sequential('ToolResultDisplay', () => {
overflowDirection="top"
/>,
{
config: makeFakeConfig({ useAlternateBuffer: false }),
config: makeFakeConfig({
useAlternateBuffer: false,
}) as unknown as Config,
settings: createMockSettings({ ui: { useAlternateBuffer: false } }),
uiState: { constrainHeight: true, terminalHeight: 10 },
},
@@ -6,7 +6,7 @@
import { useState, useRef, useCallback, useMemo } from 'react';
import type { HistoryItem } from '../types.js';
import type { ChatRecordingService } from '@google/gemini-cli-core/src/services/chatRecordingService.js';
import { type ChatRecordingService } from '@google/gemini-cli-core';
// Type for the updater function passed to updateHistoryItem
type HistoryItemUpdater = (
+3 -2
View File
@@ -18,8 +18,9 @@ import { cleanup } from './src/test-utils/render.js';
// Globally mock ink-spinner to prevent non-deterministic snapshot/act flakes.
mockInkSpinner();
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(global as any).IS_REACT_ACT_ENVIRONMENT = true;
(
global as typeof global & { IS_REACT_ACT_ENVIRONMENT: boolean }
).IS_REACT_ACT_ENVIRONMENT = true;
// Increase max listeners to avoid warnings in large test suites
coreEvents.setMaxListeners(0);
+1
View File
@@ -48,3 +48,4 @@ export { getCodeAssistServer } from './src/code_assist/codeAssist.js';
export { getExperiments } from './src/code_assist/experiments/experiments.js';
export { ExperimentFlags } from './src/code_assist/experiments/flagNames.js';
export { getErrorStatus, ModelNotFoundError } from './src/utils/httpErrors.js';
export { ChatRecordingService } from './src/services/chatRecordingService.js';
@@ -74,7 +74,7 @@ declare module 'vitest' {
}
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
interface Assertion<T = any> extends CustomMatchers<T> {}
interface Assertion<T> extends CustomMatchers<T> {}
}
expect.extend({
@@ -823,8 +823,12 @@ describe('ClearcutLogger', () => {
const { logger } = setup();
// Spy on flushToClearcut to prevent it from clearing the queue
const flushSpy = vi
.spyOn(logger!, 'flushToClearcut' as any)
.spyOn(
(logger as unknown as {
flushToClearcut: () => Promise<{ nextRequestWaitMs: number }>;
}),
'flushToClearcut',
)
.mockResolvedValue({ nextRequestWaitMs: 0 });
logger?.logRipgrepFallbackEvent();
@@ -1485,8 +1489,12 @@ describe('ClearcutLogger', () => {
it('should not flush if the interval has not passed', () => {
const { logger } = setup();
const flushSpy = vi
.spyOn(logger!, 'flushToClearcut' as any)
.spyOn(
(logger as unknown as {
flushToClearcut: () => Promise<{ nextRequestWaitMs: number }>;
}),
'flushToClearcut',
)
.mockResolvedValue({ nextRequestWaitMs: 0 });
logger!.flushIfNeeded();
@@ -1496,8 +1504,12 @@ describe('ClearcutLogger', () => {
it('should flush if the interval has passed', async () => {
const { logger } = setup();
const flushSpy = vi
.spyOn(logger!, 'flushToClearcut' as any)
.spyOn(
(logger as unknown as {
flushToClearcut: () => Promise<{ nextRequestWaitMs: number }>;
}),
'flushToClearcut',
)
.mockResolvedValue({ nextRequestWaitMs: 0 });
// Advance time by more than the flush interval
+3 -2
View File
@@ -60,9 +60,10 @@ async function main() {
cwd: process.cwd(),
});
const session = agent.session();
console.log("Sending prompt: 'What is my current session context?'");
// eslint-disable-next-line @typescript-eslint/no-explicit-any
for await (const chunk of (agent as any).sendStream(
for await (const chunk of session.sendStream(
'What is my current session context?',
)) {
if (chunk.type === 'content') {
+3 -2
View File
@@ -27,9 +27,10 @@ async function main() {
tools: [myTool],
});
const session = agent.session();
console.log("Sending prompt: 'add 5 + 6'");
// eslint-disable-next-line @typescript-eslint/no-explicit-any
for await (const chunk of (agent as any).sendStream(
for await (const chunk of session.sendStream(
'add 5 + 6 and tell me a story involving the result',
)) {
console.log(JSON.stringify(chunk, null, 2));
+19 -6
View File
@@ -246,8 +246,19 @@ describe('CPU Performance Tests', () => {
JSON.stringify(toolLatencyMetric),
);
}
const logs = (rig as any)._readAndParseTelemetryLog();
interface TelemetryLogEntry {
scopeMetrics?: {
metrics: {
descriptor: { name: string };
}[];
}[];
}
const logs = (
rig as unknown as {
_readAndParseTelemetryLog: () => TelemetryLogEntry[];
}
)._readAndParseTelemetryLog();
console.log(` Total telemetry log entries: ${logs.length}`);
for (const logData of logs) {
if (logData.scopeMetrics) {
@@ -271,10 +282,12 @@ describe('CPU Performance Tests', () => {
);
const findValue = (percentile: string) => {
const dp = (eventLoopMetric['dataPoints'] as any[]).find(
(p: any) => p.attributes.percentile === percentile,
);
const dp = (
eventLoopMetric['dataPoints'] as {
attributes: { percentile: string };
value: { min: number };
}[]
).find((p) => p.attributes.percentile === percentile);
return dp ? dp.value.min : undefined;
};
+3 -2
View File
@@ -49,8 +49,9 @@ describe('telemetry_gcp.js', () => {
await import('../telemetry_gcp.js');
expect(mockSpawn).toHaveBeenCalled();
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const spawnOptions = (mockSpawn.mock.calls[0] as any[])[2];
const spawnOptions = (
mockSpawn.mock.calls[0] as { env?: Record<string, string> }[]
)[2];
expect(spawnOptions?.env).not.toHaveProperty(
'GOOGLE_APPLICATION_CREDENTIALS',
);