Skip to content

Commit fdda329

Browse files
committed
feat: Avoid usage of any
This makes the lint rule error, instead of warn, and gets rid of some more any usage. Some of that may technically be breaking because the types can be exposed, but this should be very unlikely to affect any users.
1 parent 062204a commit fdda329

File tree

33 files changed

+121
-78
lines changed

33 files changed

+121
-78
lines changed

packages/core/src/fetch.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,8 @@ export function instrumentFetchRequest(
6666
spans[span.spanContext().spanId] = span;
6767

6868
if (shouldAttachHeaders(handlerData.fetchData.url)) {
69-
const request: string | Request = handlerData.args[0];
70-
71-
const options: { [key: string]: unknown } = handlerData.args[1] || {};
69+
const request = handlerData.args[0] as string | Request;
70+
const options = (handlerData.args[1] || {}) as Record<string, unknown>;
7271

7372
const headers = _addTracingHeadersToFetchRequest(
7473
request,

packages/core/src/integrations/supabase.ts

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { defineIntegration } from '../integration';
99
import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '../semanticAttributes';
1010
import { setHttpStatus, SPAN_STATUS_ERROR, SPAN_STATUS_OK, startSpan } from '../tracing';
1111
import type { IntegrationFn } from '../types-hoist/integration';
12+
import type { SpanAttributes } from '../types-hoist/span';
1213
import { isPlainObject } from '../utils/is';
1314
import { debug } from '../utils/logger';
1415

@@ -64,7 +65,8 @@ export const FILTER_MAPPINGS = {
6465
not: 'not',
6566
};
6667

67-
export const DB_OPERATIONS_TO_INSTRUMENT = ['select', 'insert', 'upsert', 'update', 'delete'];
68+
export const DB_OPERATIONS_TO_INSTRUMENT = ['select', 'insert', 'upsert', 'update', 'delete'] as const;
69+
type DBOperation = (typeof DB_OPERATIONS_TO_INSTRUMENT)[number];
6870

6971
type AuthOperationFn = (...args: unknown[]) => Promise<unknown>;
7072
type AuthOperationName = (typeof AUTH_OPERATIONS_TO_INSTRUMENT)[number];
@@ -86,7 +88,7 @@ export interface PostgRESTFilterBuilder {
8688
headers: Record<string, string>;
8789
url: URL;
8890
schema: string;
89-
body: any;
91+
body: unknown;
9092
}
9193

9294
export interface SupabaseResponse {
@@ -122,7 +124,7 @@ export interface SupabaseClientConstructor {
122124
export interface PostgRESTProtoThenable {
123125
then: <T>(
124126
onfulfilled?: ((value: T) => T | PromiseLike<T>) | null,
125-
onrejected?: ((reason: any) => T | PromiseLike<T>) | null,
127+
onrejected?: ((reason: unknown) => T | PromiseLike<T>) | null,
126128
) => Promise<T>;
127129
}
128130

@@ -152,7 +154,7 @@ function isInstrumented<T>(fn: T): boolean | undefined {
152154
* @param headers - The request headers
153155
* @returns The database operation type ('select', 'insert', 'upsert', 'update', or 'delete')
154156
*/
155-
export function extractOperation(method: string, headers: Record<string, string> = {}): string {
157+
export function extractOperation(method: string, headers: Record<string, string> = {}): DBOperation | '<unknown-op>' {
156158
switch (method) {
157159
case 'GET': {
158160
return 'select';
@@ -333,7 +335,7 @@ function instrumentPostgRESTFilterBuilder(PostgRESTFilterBuilder: PostgRESTFilte
333335
const typedThis = thisArg as PostgRESTFilterBuilder;
334336
const operation = extractOperation(typedThis.method, typedThis.headers);
335337

336-
if (!operations.includes(operation)) {
338+
if (!operations.includes(operation as DBOperation)) {
337339
return Reflect.apply(target, thisArg, argumentsList);
338340
}
339341

@@ -364,7 +366,7 @@ function instrumentPostgRESTFilterBuilder(PostgRESTFilterBuilder: PostgRESTFilte
364366
' ',
365367
)} from(${table})`;
366368

367-
const attributes: Record<string, any> = {
369+
const attributes: SpanAttributes = {
368370
'db.table': table,
369371
'db.schema': typedThis.schema,
370372
'db.url': typedThis.url.origin,
@@ -380,7 +382,11 @@ function instrumentPostgRESTFilterBuilder(PostgRESTFilterBuilder: PostgRESTFilte
380382
}
381383

382384
if (Object.keys(body).length) {
383-
attributes['db.body'] = body;
385+
try {
386+
attributes['db.body'] = JSON.stringify(body);
387+
} catch {
388+
// could not stringify body
389+
}
384390
}
385391

386392
return startSpan(
@@ -465,17 +471,19 @@ function instrumentPostgRESTFilterBuilder(PostgRESTFilterBuilder: PostgRESTFilte
465471
markAsInstrumented((PostgRESTFilterBuilder.prototype as unknown as PostgRESTProtoThenable).then);
466472
}
467473

474+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
475+
type BuilderPrototype = Record<DBOperation, (...args: any[]) => any>;
476+
468477
function instrumentPostgRESTQueryBuilder(PostgRESTQueryBuilder: new () => PostgRESTQueryBuilder): void {
469478
// We need to wrap _all_ operations despite them sharing the same `PostgRESTFilterBuilder`
470479
// constructor, as we don't know which method will be called first, and we don't want to miss any calls.
471480
for (const operation of DB_OPERATIONS_TO_INSTRUMENT) {
472-
if (isInstrumented((PostgRESTQueryBuilder.prototype as Record<string, any>)[operation])) {
481+
if (isInstrumented((PostgRESTQueryBuilder.prototype as BuilderPrototype)[operation])) {
473482
continue;
474483
}
475484

476-
type PostgRESTOperation = keyof Pick<PostgRESTQueryBuilder, 'select' | 'insert' | 'upsert' | 'update' | 'delete'>;
477-
(PostgRESTQueryBuilder.prototype as Record<string, any>)[operation as PostgRESTOperation] = new Proxy(
478-
(PostgRESTQueryBuilder.prototype as Record<string, any>)[operation as PostgRESTOperation],
485+
(PostgRESTQueryBuilder.prototype as BuilderPrototype)[operation] = new Proxy(
486+
(PostgRESTQueryBuilder.prototype as BuilderPrototype)[operation],
479487
{
480488
apply(target, thisArg, argumentsList) {
481489
const rv = Reflect.apply(target, thisArg, argumentsList);
@@ -490,7 +498,7 @@ function instrumentPostgRESTQueryBuilder(PostgRESTQueryBuilder: new () => PostgR
490498
},
491499
);
492500

493-
markAsInstrumented((PostgRESTQueryBuilder.prototype as Record<string, any>)[operation]);
501+
markAsInstrumented((PostgRESTQueryBuilder.prototype as BuilderPrototype)[operation]);
494502
}
495503
}
496504

@@ -517,6 +525,7 @@ const _supabaseIntegration = ((supabaseClient: unknown) => {
517525
};
518526
}) satisfies IntegrationFn;
519527

528+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
520529
export const supabaseIntegration = defineIntegration((options: { supabaseClient: any }) => {
521530
return _supabaseIntegration(options.supabaseClient);
522531
}) satisfies IntegrationFn;

packages/core/src/profiling.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1+
import type { Client } from './client';
12
import { getClient } from './currentScopes';
23
import { DEBUG_BUILD } from './debug-build';
34
import type { Profiler, ProfilingIntegration } from './types-hoist/profiling';
45
import { debug } from './utils/logger';
56

67
function isProfilingIntegrationWithProfiler(
7-
integration: ProfilingIntegration<any> | undefined,
8-
): integration is ProfilingIntegration<any> {
8+
integration: ProfilingIntegration<Client> | undefined,
9+
): integration is ProfilingIntegration<Client> {
910
return (
1011
!!integration &&
1112
typeof integration['_profiler'] !== 'undefined' &&
@@ -25,7 +26,7 @@ function startProfiler(): void {
2526
return;
2627
}
2728

28-
const integration = client.getIntegrationByName<ProfilingIntegration<any>>('ProfilingIntegration');
29+
const integration = client.getIntegrationByName<ProfilingIntegration<Client>>('ProfilingIntegration');
2930

3031
if (!integration) {
3132
DEBUG_BUILD && debug.warn('ProfilingIntegration is not available');
@@ -51,7 +52,7 @@ function stopProfiler(): void {
5152
return;
5253
}
5354

54-
const integration = client.getIntegrationByName<ProfilingIntegration<any>>('ProfilingIntegration');
55+
const integration = client.getIntegrationByName<ProfilingIntegration<Client>>('ProfilingIntegration');
5556
if (!integration) {
5657
DEBUG_BUILD && debug.warn('ProfilingIntegration is not available');
5758
return;

packages/core/src/types-hoist/breadcrumb.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,10 @@ export interface Breadcrumb {
5252
*
5353
* @summary Arbitrary data associated with this breadcrumb.
5454
*/
55-
data?: { [key: string]: any };
55+
// Note: we cannot use Record<string, unknown> here because it's not compatible with interface data types
56+
// See: https://github.com/microsoft/TypeScript/issues/15300
57+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
58+
data?: Record<string, any>;
5659

5760
/**
5861
* The format is a numeric (integer or float) value representing
@@ -70,6 +73,9 @@ export interface Breadcrumb {
7073

7174
/** JSDoc */
7275
export interface BreadcrumbHint {
76+
// Note: we cannot use unknown here because it's not compatible with interface data types
77+
// See: https://github.com/microsoft/TypeScript/issues/15300
78+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
7379
[key: string]: any;
7480
}
7581

@@ -90,7 +96,7 @@ export interface XhrBreadcrumbData {
9096
}
9197

9298
export interface FetchBreadcrumbHint {
93-
input: any[];
99+
input: unknown[];
94100
data?: unknown;
95101
response?: unknown;
96102
startTimestamp: number;

packages/core/src/types-hoist/context.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { FeatureFlag } from '../utils/featureFlags';
22
import type { SpanLinkJSON } from './link';
33
import type { Primitive } from './misc';
4-
import type { SpanOrigin } from './span';
4+
import type { SpanAttributes, SpanOrigin } from './span';
55

66
export type Context = Record<string, unknown>;
77

@@ -99,7 +99,7 @@ export interface ResponseContext extends Record<string, unknown> {
9999
}
100100

101101
export interface TraceContext extends Record<string, unknown> {
102-
data?: { [key: string]: any };
102+
data?: SpanAttributes;
103103
op?: string;
104104
parent_span_id?: string;
105105
span_id: string;

packages/core/src/types-hoist/error.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
* Just an Error object with arbitrary attributes attached to it.
33
*/
44
export interface ExtendedError extends Error {
5-
[key: string]: any;
5+
[key: string]: unknown;
66
}

packages/core/src/types-hoist/event.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,6 @@ export interface EventHint {
8383
syntheticException?: Error | null;
8484
originalException?: unknown;
8585
attachments?: Attachment[];
86-
data?: any;
86+
data?: unknown;
8787
integrations?: string[];
8888
}

packages/core/src/types-hoist/feedback/config.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { Primitive } from '../misc';
2+
import type { User } from '../user';
23
import type { FeedbackFormData } from './form';
34
import type { FeedbackTheme } from './theme';
45

@@ -53,8 +54,8 @@ export interface FeedbackGeneralConfiguration {
5354
* The value of the email/name keys represent the properties of your user context.
5455
*/
5556
useSentryUser: {
56-
email: string;
57-
name: string;
57+
email: keyof User;
58+
name: keyof User;
5859
};
5960

6061
/**

packages/core/src/types-hoist/instrument.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ interface SentryFetchData {
4747
}
4848

4949
export interface HandlerDataFetch {
50-
args: any[];
50+
args: unknown[];
5151
fetchData: SentryFetchData; // This data is among other things dumped directly onto the fetch breadcrumb data
5252
startTimestamp: number;
5353
endTimestamp?: number;
@@ -74,7 +74,7 @@ export interface HandlerDataDom {
7474

7575
export interface HandlerDataConsole {
7676
level: ConsoleLevel;
77-
args: any[];
77+
args: unknown[];
7878
}
7979

8080
export interface HandlerDataHistory {

packages/core/src/types-hoist/integration.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,5 @@ export interface Integration {
4747
* An integration in function form.
4848
* This is expected to return an integration.
4949
*/
50+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
5051
export type IntegrationFn<IntegrationType = Integration> = (...rest: any[]) => IntegrationType;

0 commit comments

Comments
 (0)