Skip to content

Commit db5520f

Browse files
BenoitZugmeyercy-moithomas-lebeau
authored
📦️ update typescript-eslint (#3192)
* 📦️ update typescript-eslint and adjust config We still use the ("legacy setup")[1] on purpose: we'll upgrade to a flat config in a separate PR, when we upgrade ESLint. [1]: https://typescript-eslint.io/getting-started/legacy-eslint-setup Rule changes: * @typescript-eslint/ban-types have been split in multiple rules, most of them are enabled by default. The configuration we used has been ported to @typescript-eslint/no-restricted-types * no-throw-literal isn't needed anymore as the new rule @typescript-eslint/only-throw-error is covering the same thing and more. * @typescript-eslint/no-var-requires was replaced with @typescript-eslint/no-require-imports. * @typescript-eslint/no-unused-experessions was turned on in the recommended rules, but we have a few cases where we avoid using an `if` like `foo && bar()` that raise that error, so I disabled the rule for now. * 🚨 fix lint issues related to typescript-eslint update * The new @typescript-eslint/only-throw-error reports quite a few (valid) cases where we don't throw errors. I ignored those as issues as this was generally what we wanted. * Some eslint-disable comments were not needed, so I removed them * Optional properties and arguments that also accept `undefined` now raise an error * typescript-eslint is also better at finding unused variables in catch clauses * And other minor things... * Turn on rule no-unused-expressions * Update developer-extension/src/panel/components/tabs/infosTab.tsx Co-authored-by: Thomas Lebeau <[email protected]> --------- Co-authored-by: zcy <[email protected]> Co-authored-by: Thomas Lebeau <[email protected]>
1 parent b9b2592 commit db5520f

33 files changed

+139
-99
lines changed

.eslintrc.js

+22-5
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,26 @@ module.exports = {
2020
'./performances/tsconfig.json',
2121
],
2222
sourceType: 'module',
23+
24+
// Without this option, typescript-eslint fails to lint .js files because we don't use
25+
// `allowJs: true` in the TypeScript configuration. Same issue as
26+
// https://github.com/typescript-eslint/typescript-eslint/issues/9749.
27+
//
28+
// Enabling `allowJs` would be a better solution, but right now it's not possible because of a
29+
// pretty small reason with big implications: `webpack.base.js` includes
30+
// `tsconfig-paths-webpack-plugin`, and this file includes Node.js types via a <reference>
31+
// directive (see https://unpkg.com/browse/[email protected]/lib/plugin.d.ts).
32+
//
33+
// Because of this, Node.js types are included in the whole project, and because some of them
34+
// are slightly different from the DOM/Browser types, some annoying typecheck errors are raised.
35+
//
36+
// So, ideally, we should:
37+
// * add `allowJs: true` in the TypeScript configuration
38+
// * have different tsconfig.json configurations for packages and scripts
39+
// * when typechecking, run `tsc` multiple time with each configuration (like we do for the
40+
// developer-extension)
41+
// * then remove this option
42+
disallowAutomaticSingleRunInference: true,
2343
},
2444
plugins: [
2545
'eslint-plugin-import',
@@ -60,7 +80,6 @@ module.exports = {
6080
'no-return-await': 'error',
6181
'no-sequences': 'error',
6282
'no-template-curly-in-string': 'error',
63-
'no-throw-literal': 'error',
6483
'no-undef-init': 'error',
6584
'no-unreachable': 'error',
6685
'no-useless-concat': 'error',
@@ -94,14 +113,12 @@ module.exports = {
94113
'ts-check': 'allow-with-description',
95114
},
96115
],
97-
'@typescript-eslint/ban-types': [
116+
'@typescript-eslint/no-restricted-types': [
98117
'error',
99118
{
100119
types: {
101120
/* eslint-disable id-denylist */
102121
Object: { message: 'Avoid using the `Object` type. Did you mean `object`?' },
103-
object: false,
104-
Function: { message: 'Avoid using the `Function` type. Prefer a specific function type, like `() => void`.' },
105122
Boolean: { message: 'Avoid using the `Boolean` type. Did you mean `boolean`?' },
106123
Number: { message: 'Avoid using the `Number` type. Did you mean `number`?' },
107124
String: { message: 'Avoid using the `String` type. Did you mean `string`?' },
@@ -288,7 +305,7 @@ module.exports = {
288305
node: true,
289306
},
290307
rules: {
291-
'@typescript-eslint/no-var-requires': 'off',
308+
'@typescript-eslint/no-require-imports': 'off',
292309
},
293310
},
294311
{

developer-extension/src/panel/components/panel.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export function Panel() {
3030
const [activeTab, setActiveTab] = useState<string | null>(DEFAULT_PANEL_TAB)
3131
function updateActiveTab(activeTab: string | null) {
3232
setActiveTab(activeTab)
33-
activeTab && datadogRum.startView(activeTab)
33+
datadogRum.startView(activeTab!)
3434
}
3535

3636
return (

developer-extension/src/panel/components/tabs/infosTab.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ function Entry({
169169
}
170170

171171
const handleClearClick = () => {
172-
onChange && onChange(null)
172+
onChange?.(null)
173173
reloadPage()
174174
}
175175

developer-extension/src/panel/hooks/useSettings.ts

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ export function useSettings() {
5757
// If we don't have settings yet, it means that we are still loading them from the storage. Throw
5858
// the promise so it'll be caught by the Suspense boundary.
5959
if (!settings) {
60+
// eslint-disable-next-line @typescript-eslint/only-throw-error
6061
throw storageLoadingPromise
6162
}
6263

developer-extension/src/panel/index.tsx

-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// The default eslint-plugin-import resolver does not support "exports" fields in package.json yet.
22
// Ignore the error until the default resolver supports it, or we switch to a different resolver.
33
// https://github.com/import-js/eslint-plugin-import/issues/1810
4-
// eslint-disable-next-line import/no-unresolved
54
import '@mantine/core/styles.layer.css'
65

76
import './global.css'

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@
3737
"@types/cors": "2.8.17",
3838
"@types/express": "4.17.21",
3939
"@types/jasmine": "3.10.18",
40-
"@typescript-eslint/eslint-plugin": "7.18.0",
41-
"@typescript-eslint/parser": "7.18.0",
40+
"@typescript-eslint/eslint-plugin": "8.16.0",
41+
"@typescript-eslint/parser": "8.16.0",
4242
"@wdio/browserstack-service": "8.40.6",
4343
"@wdio/cli": "8.40.6",
4444
"@wdio/jasmine-framework": "8.40.6",

packages/core/src/boot/init.spec.ts

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ describe('defineGlobal', () => {
3434
it('catches the errors thrown by the queued callbacks', () => {
3535
const myError = 'Ooops!'
3636
const onReady = () => {
37+
// eslint-disable-next-line @typescript-eslint/only-throw-error
3738
throw myError
3839
}
3940
const myGlobal: any = {

packages/core/src/browser/browser.types.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ export interface WeakRefConstructor {
5353

5454
// Those are native API types that are not official supported by TypeScript yet
5555

56+
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
5657
export interface CookieStore extends EventTarget {}
5758

5859
export interface CookieStoreEventMap {
@@ -65,5 +66,3 @@ export type CookieChangeEvent = Event & {
6566
changed: CookieChangeItem[]
6667
deleted: CookieChangeItem[]
6768
}
68-
69-
export interface CookieStore extends EventTarget {}

packages/core/src/domain/configuration/configuration.spec.ts

+1
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ describe('validateAndBuildConfiguration', () => {
155155
it('should catch errors and log them', () => {
156156
const myError = 'Ooops!'
157157
const beforeSend = () => {
158+
// eslint-disable-next-line @typescript-eslint/only-throw-error
158159
throw myError
159160
}
160161
const configuration = validateAndBuildConfiguration({ clientToken, beforeSend })!

packages/core/src/domain/console/consoleObservable.spec.ts

-2
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,6 @@ describe('console error observable', () => {
118118
const error = new Error('foo')
119119
;(error as DatadogError).dd_fingerprint = 'my-fingerprint'
120120

121-
// eslint-disable-next-line no-console
122121
console.error(error)
123122

124123
const consoleLog = notifyLog.calls.mostRecent().args[0]
@@ -129,7 +128,6 @@ describe('console error observable', () => {
129128
const error = new Error('foo')
130129
;(error as any).dd_fingerprint = 2
131130

132-
// eslint-disable-next-line no-console
133131
console.error(error)
134132

135133
const consoleLog = notifyLog.calls.mostRecent().args[0]

packages/core/src/domain/context/contextManager.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export function createContextManager(customerDataTracker?: CustomerDataTracker)
1717
setContext: (newContext: Context) => {
1818
if (getType(newContext) === 'object') {
1919
context = sanitize(newContext)
20-
customerDataTracker && customerDataTracker.updateCustomerData(context)
20+
customerDataTracker?.updateCustomerData(context)
2121
} else {
2222
contextManager.clearContext()
2323
}
@@ -26,19 +26,19 @@ export function createContextManager(customerDataTracker?: CustomerDataTracker)
2626

2727
setContextProperty: (key: string, property: any) => {
2828
context[key] = sanitize(property)
29-
customerDataTracker && customerDataTracker.updateCustomerData(context)
29+
customerDataTracker?.updateCustomerData(context)
3030
changeObservable.notify()
3131
},
3232

3333
removeContextProperty: (key: string) => {
3434
delete context[key]
35-
customerDataTracker && customerDataTracker.updateCustomerData(context)
35+
customerDataTracker?.updateCustomerData(context)
3636
changeObservable.notify()
3737
},
3838

3939
clearContext: () => {
4040
context = {}
41-
customerDataTracker && customerDataTracker.resetCustomerData()
41+
customerDataTracker?.resetCustomerData()
4242
changeObservable.notify()
4343
},
4444

packages/core/src/domain/error/trackRuntimeError.spec.ts

-2
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,6 @@ describe('instrumentOnError', () => {
113113
it('should notify unhandled string', (done) => {
114114
const error = 'foo' as any
115115
setTimeout(() => {
116-
// eslint-disable-next-line no-throw-literal
117116
throw error
118117
})
119118
collectAsyncCalls(onErrorSpy, 1, () => {
@@ -127,7 +126,6 @@ describe('instrumentOnError', () => {
127126
it('should notify unhandled object', (done) => {
128127
const error = { a: 'foo' } as any
129128
setTimeout(() => {
130-
// eslint-disable-next-line no-throw-literal
131129
throw error
132130
})
133131
collectAsyncCalls(onErrorSpy, 1, () => {

packages/core/src/domain/session/sessionStoreOperations.spec.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ const EXPIRED_SESSION: SessionState = { isExpired: '1' }
4747

4848
describe('with lock access disabled', () => {
4949
beforeEach(() => {
50-
sessionStoreStrategy.isLockEnabled && pending('lock-access required')
50+
if (sessionStoreStrategy.isLockEnabled) {
51+
pending('lock-access required')
52+
}
5153
})
5254

5355
it('should persist session when process returns a value', () => {
@@ -99,7 +101,9 @@ const EXPIRED_SESSION: SessionState = { isExpired: '1' }
99101

100102
describe('with lock access enabled', () => {
101103
beforeEach(() => {
102-
!sessionStoreStrategy.isLockEnabled && pending('lock-access not enabled')
104+
if (!sessionStoreStrategy.isLockEnabled) {
105+
pending('lock-access not enabled')
106+
}
103107
})
104108

105109
it('should persist session when process returns a value', () => {

packages/core/src/domain/session/sessionStoreOperations.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,11 @@ export function processSessionStoreOperations(
7979
expireSession(processedSession)
8080
} else {
8181
expandSessionState(processedSession)
82-
isLockEnabled ? persistWithLock(processedSession) : persistSession(processedSession)
82+
if (isLockEnabled) {
83+
persistWithLock(processedSession)
84+
} else {
85+
persistSession(processedSession)
86+
}
8387
}
8488
}
8589
if (isLockEnabled) {

packages/core/src/domain/session/storeStrategies/sessionInLocalStorage.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export function selectLocalStorageStrategy(): SessionStoreStrategyType | undefin
1414
const retrievedId = localStorage.getItem(testKey)
1515
localStorage.removeItem(testKey)
1616
return id === retrievedId ? { type: 'LocalStorage' } : undefined
17-
} catch (e) {
17+
} catch {
1818
return undefined
1919
}
2020
}

packages/core/src/tools/catchUserErrors.spec.ts

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ describe('catchUserErrors', () => {
1111
const displaySpy = spyOn(display, 'error')
1212
const myError = 'Ooops!'
1313
const wrappedFn = catchUserErrors(() => {
14+
// eslint-disable-next-line @typescript-eslint/only-throw-error
1415
throw myError
1516
}, 'Error during callback')
1617
expect(wrappedFn()).toBe(undefined)

packages/core/src/tools/experimentalFeatures.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export enum ExperimentalFeature {
2424

2525
const enabledExperimentalFeatures: Set<ExperimentalFeature> = new Set()
2626

27-
export function initFeatureFlags(enableExperimentalFeatures?: string[] | undefined) {
27+
export function initFeatureFlags(enableExperimentalFeatures: string[] | undefined) {
2828
if (Array.isArray(enableExperimentalFeatures)) {
2929
addExperimentalFeatures(
3030
enableExperimentalFeatures.filter((flag): flag is ExperimentalFeature =>

packages/core/src/tools/monitor.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,13 @@ describe('monitor', () => {
2020

2121
@monitored
2222
monitoredStringErrorThrowing() {
23-
// eslint-disable-next-line no-throw-literal
23+
// eslint-disable-next-line @typescript-eslint/only-throw-error
2424
throw 'string error'
2525
}
2626

2727
@monitored
2828
monitoredObjectErrorThrowing() {
29-
// eslint-disable-next-line no-throw-literal
29+
// eslint-disable-next-line @typescript-eslint/only-throw-error
3030
throw { foo: 'bar' }
3131
}
3232

packages/core/src/tools/serialisation/context.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ export interface Context {
44

55
export type ContextValue = string | number | boolean | Context | ContextArray | undefined | null
66

7-
// eslint-disable-next-line @typescript-eslint/no-empty-interface
7+
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
88
export interface ContextArray extends Array<ContextValue> {}

packages/core/src/tools/serialisation/sanitize.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import type { Context, ContextArray, ContextValue } from './context'
44
import type { ObjectWithToJsonMethod } from './jsonStringify'
55
import { detachToJsonMethod } from './jsonStringify'
66

7-
// eslint-disable-next-line @typescript-eslint/ban-types
7+
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
88
type PrimitivesAndFunctions = string | number | boolean | undefined | null | symbol | bigint | Function
99
type ExtendedContextValue = PrimitivesAndFunctions | object | ExtendedContext | ExtendedContextArray
1010
type ExtendedContext = { [key: string]: ExtendedContextValue }

packages/core/src/tools/stackTrace/handlingStack.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export function createHandlingStack(): string {
2424
if (!error.stack) {
2525
try {
2626
throw error
27-
} catch (e) {
27+
} catch {
2828
noop()
2929
}
3030
}

packages/core/src/tools/utils/responseUtils.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export function isServerError(status: number) {
55
export function tryToClone(response: Response): Response | undefined {
66
try {
77
return response.clone()
8-
} catch (e) {
8+
} catch {
99
// clone can throw if the response has already been used by another instrumentation or is disturbed
1010
return
1111
}

packages/core/src/transport/httpRequest.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ describe('httpRequest', () => {
5757
}
5858
let notQueuedFetch: Promise<never>
5959
interceptor.withFetch(() => {
60-
notQueuedFetch = Promise.reject()
60+
notQueuedFetch = Promise.reject(new Error())
6161
return notQueuedFetch
6262
})
6363

@@ -118,7 +118,7 @@ describe('httpRequest', () => {
118118
pending('no fetch keepalive support')
119119
}
120120

121-
interceptor.withFetch(() => Promise.reject())
121+
interceptor.withFetch(() => Promise.reject(new Error()))
122122
interceptor.withMockXhr((xhr) => {
123123
setTimeout(() => {
124124
xhr.complete(429)

packages/logs/src/boot/logsPublicApi.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ describe('logs entry', () => {
1818
(
1919
logsMessage: LogsMessage,
2020
logger: Logger,
21-
commonContext?: CommonContext | undefined,
22-
date?: TimeStamp | undefined
21+
commonContext: CommonContext | undefined,
22+
date: TimeStamp | undefined
2323
) => void
2424
>
2525
let startLogs: jasmine.Spy<StartLogs>

packages/logs/src/boot/logsPublicApi.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ export interface LogsPublicApi extends PublicApi {
119119
*
120120
* See [Access internal context](https://docs.datadoghq.com/logs/log_collection/javascript/#access-internal-context) for further information.
121121
*/
122-
getInternalContext: (startTime?: number | undefined) => InternalContext | undefined
122+
getInternalContext: (startTime?: number) => InternalContext | undefined
123123

124124
/**
125125
* Set user information to all events, stored in `@usr`

packages/logs/src/domain/runtimeError/runtimeErrorCollection.spec.ts

+1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ describe('runtime error collection', () => {
7070
error.cause = nestedError
7171
;({ stop: stopRuntimeErrorCollection } = startRuntimeErrorCollection(configuration, lifeCycle))
7272
setTimeout(() => {
73+
// eslint-disable-next-line @typescript-eslint/only-throw-error
7374
throw error
7475
})
7576

packages/rum-core/src/browser/htmlDomUtils.spec.ts

+4
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ describe('isTextNode', () => {
2121
]
2222

2323
parameters.forEach(([element, result]) => {
24+
// eslint-disable-next-line @typescript-eslint/no-base-to-string
2425
it(`should return ${String(result)} for "${String(element)}"`, () => {
2526
expect(isTextNode(element)).toBe(result)
2627
})
@@ -37,6 +38,7 @@ describe('isCommentNode', () => {
3738
]
3839

3940
parameters.forEach(([element, result]) => {
41+
// eslint-disable-next-line @typescript-eslint/no-base-to-string
4042
it(`should return ${String(result)} for "${String(element)}"`, () => {
4143
expect(isCommentNode(element)).toBe(result)
4244
})
@@ -53,6 +55,7 @@ describe('isElementNode', () => {
5355
]
5456

5557
parameters.forEach(([element, result]) => {
58+
// eslint-disable-next-line @typescript-eslint/no-base-to-string
5659
it(`should return ${String(result)} for "${String(element)}"`, () => {
5760
expect(isElementNode(element)).toBe(result)
5861
})
@@ -119,6 +122,7 @@ if (!isIE()) {
119122
]
120123

121124
parameters.forEach(([element, result]) => {
125+
// eslint-disable-next-line @typescript-eslint/no-base-to-string
122126
it(`should return ${String(result)} for "${String(element)}"`, () => {
123127
expect(isNodeShadowHost(element)).toBe(result)
124128
})

packages/rum-core/src/domain/view/viewMetrics/trackInteractionToNextPaint.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ describe('trackInteractionToNextPaint', () => {
5252
setViewEnd = interactionToNextPaintTracking.setViewEnd
5353

5454
registerCleanupTask(() => {
55-
interactionToNextPaintTracking.stop
55+
interactionToNextPaintTracking.stop()
5656
resetExperimentalFeatures()
5757
interactionCountMock.clear()
5858
})

0 commit comments

Comments
 (0)