From c3113cf8e15f3ed9a4046f36a5d17b2302cd60ea Mon Sep 17 00:00:00 2001 From: Alfonso Noriega Date: Mon, 13 Apr 2026 16:11:55 +0200 Subject: [PATCH] refactor: replace unsafe 'as any' casts with proper types in cli-kit Replaced 5 'as any' casts in production code with type-safe alternatives: - error.ts: Use Record + typeof guards instead of 'as any' - cli.ts: Access PackageJson.name directly (already typed as optional) - metadata.ts: Use PerformanceMeasureOptions instead of 'as any' - plugins.ts: Use the actual generic return type instead of 'as any' Each change removes an eslint-disable comment and makes the code safer against runtime type mismatches. --- packages/cli-kit/src/public/node/cli.ts | 3 +-- packages/cli-kit/src/public/node/error.ts | 10 +++++----- packages/cli-kit/src/public/node/metadata.ts | 8 +++----- packages/cli-kit/src/public/node/plugins.ts | 5 +++-- 4 files changed, 12 insertions(+), 14 deletions(-) diff --git a/packages/cli-kit/src/public/node/cli.ts b/packages/cli-kit/src/public/node/cli.ts index 4adb3268f7a..35b1eb5edc8 100644 --- a/packages/cli-kit/src/public/node/cli.ts +++ b/packages/cli-kit/src/public/node/cli.ts @@ -102,8 +102,7 @@ async function addInitToArgvWhenRunningCreateCLI( const {moduleDirectory} = await import('./path.js') const packageJson = await findUpAndReadPackageJson(moduleDirectory(options.moduleURL)) - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const packageName = (packageJson.content as any).name as string + const packageName = packageJson.content.name ?? '' const name = packageName.replace('@shopify/create-', '') const initIndex = argv.findIndex((arg) => arg.includes('init')) if (initIndex === -1) { diff --git a/packages/cli-kit/src/public/node/error.ts b/packages/cli-kit/src/public/node/error.ts index 552a722e312..17e155c882c 100644 --- a/packages/cli-kit/src/public/node/error.ts +++ b/packages/cli-kit/src/public/node/error.ts @@ -138,11 +138,11 @@ export async function handler(error: unknown): Promise { fatal.stack = error.stack } else { // errors can come in all shapes and sizes... - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const maybeError = error as any - fatal = new BugError(maybeError?.message ?? 'Unknown error') - if (maybeError?.stack) { - fatal.stack = maybeError?.stack + const maybeError = error as Record + const message = typeof maybeError?.message === 'string' ? maybeError.message : 'Unknown error' + fatal = new BugError(message) + if (typeof maybeError?.stack === 'string') { + fatal.stack = maybeError.stack } } diff --git a/packages/cli-kit/src/public/node/metadata.ts b/packages/cli-kit/src/public/node/metadata.ts index ae77344aa77..30b73ac82e7 100644 --- a/packages/cli-kit/src/public/node/metadata.ts +++ b/packages/cli-kit/src/public/node/metadata.ts @@ -151,17 +151,15 @@ export function createRuntimeMetadataContainer< durationStack[durationStack.length - 1] = (durationStack[durationStack.length - 1] ?? 0) + wallClockDuration } - // Log it -- we include it in the metadata, but also log via the standard performance API. The TS types for this library are not quite right, so we have to cast to `any` here. + // Log it -- we include it in the metadata, but also log via the standard performance API. performance.measure(`${field}#measurable`, { start, duration, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - } as any) + } as PerformanceMeasureOptions) performance.measure(`${field}#wall`, { start, end, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - } as any) + } as PerformanceMeasureOptions) // There might not be a value set, yet let currentValue = (raw.public[field] || 0) as number diff --git a/packages/cli-kit/src/public/node/plugins.ts b/packages/cli-kit/src/public/node/plugins.ts index caf1189990b..bb36b9db587 100644 --- a/packages/cli-kit/src/public/node/plugins.ts +++ b/packages/cli-kit/src/public/node/plugins.ts @@ -25,8 +25,9 @@ export async function fanoutHooks> { const res = await config.runHook(event, options, timeout) - // eslint-disable-next-line @typescript-eslint/no-explicit-any - return Object.fromEntries(res.successes.map(({result, plugin}) => [plugin.name, result])) as any + return Object.fromEntries( + res.successes.map(({result, plugin}) => [plugin.name, result]), + ) as Partial } type AppSpecificMonorailFields = PickByPrefix<