Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lint(eslint): Enable no-extra-non-null-assertion and auto-fix violations #83786

Merged
merged 2 commits into from
Jan 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ export default typescript.config([
...react.configs.flat.recommended.rules,
...react.configs.flat['jsx-runtime'].rules,
'react/display-name': 'off', // TODO(ryan953): Fix violations and delete this line
'react/no-unescaped-entities': 'off', // TODO(ryan953): Fix violations and delete this line
'react/no-unescaped-entities': 'off',
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't going to happen. I tried and it's not worth it right now: #83511

'react/no-unknown-property': ['error', {ignore: ['css']}],
'react/prop-types': 'off', // TODO(ryan953): Fix violations and delete this line
},
Expand Down Expand Up @@ -418,8 +418,7 @@ export default typescript.config([
'@typescript-eslint/ban-ts-comment': 'off', // TODO(ryan953): Fix violations and delete this line
'@typescript-eslint/no-array-constructor': 'off', // TODO(ryan953): Fix violations and delete this line
'@typescript-eslint/no-empty-object-type': 'off', // TODO(ryan953): Fix violations and delete this line
'@typescript-eslint/no-explicit-any': 'off', // TODO(ryan953): Fix violations and delete this line
'@typescript-eslint/no-extra-non-null-assertion': 'off', // TODO(ryan953): Fix violations and delete this line
'@typescript-eslint/no-explicit-any': 'off',
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no-explicit-any isn't going to happen.

'@typescript-eslint/no-namespace': 'off', // TODO(ryan953): Fix violations and delete this line
'@typescript-eslint/no-non-null-asserted-optional-chain': 'off', // TODO(ryan953): Fix violations and delete this line
'@typescript-eslint/no-require-imports': 'off', // TODO(ryan953): Fix violations and delete this line
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -668,7 +668,7 @@ describe('WaterfallModel', () => {

expected[1] = {
type: 'out_of_view',
span: fullWaterfall[1]!!.span,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's an example of the automation fixing some earlier automation.

span: fullWaterfall[1]!.span,
} as EnhancedProcessedSpanType;

expected[4] = {
Expand Down Expand Up @@ -696,7 +696,7 @@ describe('WaterfallModel', () => {
},
{
type: 'out_of_view',
span: fullWaterfall[1]!!.span,
span: fullWaterfall[1]!.span,
},
fullWaterfall[2],
fullWaterfall[3],
Expand Down Expand Up @@ -884,7 +884,7 @@ describe('WaterfallModel', () => {
{
...fullWaterfall[1]!,
span: {
...fullWaterfall[1]!!.span,
...fullWaterfall[1]!.span,
parent_span_id: (event.entries[0] as any).data[0]!.span_id,
span_id: 'foo',
},
Expand Down
12 changes: 6 additions & 6 deletions static/app/components/metrics/chart/chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,14 @@ function getLegendProps(showLegend?: boolean): Pick<BaseChartProps, 'legend' | '
// But for now we keep it here to not invluence the bundle size of the main chunks.
echarts.use(CanvasRenderer);

function isNonZeroValue(value: number | null) {
return value !== null && value !== 0;
function isNonZeroValue(value: number | undefined) {
return value !== undefined && value !== 0;
}

function addSeriesPadding(data: Series['data']) {
const hasNonZeroSibling = (index: number) => {
return (
isNonZeroValue(data[index - 1]!?.value) || isNonZeroValue(data[index + 1]!?.value)
isNonZeroValue(data[index - 1]?.value!) || isNonZeroValue(data[index + 1]?.value)
);
};
const paddingIndices = new Set<number>();
Expand Down Expand Up @@ -142,11 +142,11 @@ export const MetricChart = memo(
}
});

const bucketSize = series[0]!?.data[1]!?.name - series[0]!?.data[0]!?.name;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good example where a manual fix was needed...

Before we had ! next to each of the optional fields, chained all the way down.

Now we have one ! at the end of the chain.

const bucketSize = series[0]?.data[1]?.name! - series[0]?.data[0]?.name!;
const isSubMinuteBucket = bucketSize < 60_000;
const lastBucketTimestamp = series[0]!?.data?.[series[0]!?.data?.length - 1]!?.name;
const lastBucketTimestamp = series[0]?.data[series[0]?.data.length - 1]?.name;
const ingestionBuckets = useMemo(
() => getIngestionDelayBucketCount(bucketSize, lastBucketTimestamp),
() => getIngestionDelayBucketCount(bucketSize, lastBucketTimestamp!),
[bucketSize, lastBucketTimestamp]
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ function BaseEnvironmentPageFilterTrigger(
// Show 2 environments only if the combined string's length does not exceed 25.
// Otherwise show only 1 environment.
const envsToShow =
value[0]!?.length + value[1]!?.length <= 23 ? value.slice(0, 2) : value.slice(0, 1);
value[0]?.length! + value[1]?.length! <= 23 ? value.slice(0, 2) : value.slice(0, 1);

// e.g. "production, staging"
const enumeratedLabel = envsToShow.map(env => trimSlug(env, 25)).join(', ');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ export function ProjectPageFilter({
if (!val.length) {
return allowMultiple
? memberProjects.map(p => parseInt(p.id, 10))
: [parseInt(memberProjects[0]!?.id, 10)];
: [parseInt(memberProjects[0]?.id!, 10)];
}

return allowMultiple ? val : [val[0]!];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ function BaseProjectPageFilterTrigger(
// Show 2 projects only if the combined string does not exceed maxTitleLength.
// Otherwise show only 1 project.
const projectsToShow =
selectedProjects[0]!?.slug?.length + selectedProjects[1]!?.slug?.length <= 23
selectedProjects[0]?.slug?.length! + selectedProjects[1]?.slug?.length! <= 23
? selectedProjects.slice(0, 2)
: selectedProjects.slice(0, 1);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export function PlatformOptionDropdown({
<OptionControl
key="platformOption"
option={platforms}
value={urlOptionValues.siblingOption ?? platforms.items[0]!?.label}
value={urlOptionValues.siblingOption ?? platforms.items[0]?.label!}
onChange={v => handleChange('siblingOption', v.value)}
disabled={disabled}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ describe('parseMultiSelectValue', function () {
expect(result).not.toBeNull();

expect(result!.items).toHaveLength(3);
expect(result!?.items[0]!.value?.value).toBe('a');
expect(result!?.items[1]!.value?.value).toBe('b');
expect(result!?.items[2]!.value?.value).toBe('c');
expect(result?.items[0]!.value?.value).toBe('a');
expect(result?.items[1]!.value?.value).toBe('b');
expect(result?.items[2]!.value?.value).toBe('c');
});

it('quoted value', function () {
Expand All @@ -27,11 +27,11 @@ describe('parseMultiSelectValue', function () {
expect(result).not.toBeNull();

expect(result!.items).toHaveLength(3);
expect(result!?.items[0]!.value?.value).toBe('a');
expect(result?.items[0]!.value?.value).toBe('a');

expect(result!?.items[1]!.value?.value).toBe('b');
expect(result!?.items[1]!.value?.text).toBe('"b"');
expect(result!?.items[1]!.value?.quoted).toBe(true);
expect(result?.items[1]!.value?.value).toBe('b');
expect(result?.items[1]!.value?.text).toBe('"b"');
expect(result?.items[1]!.value?.quoted).toBe(true);

expect(result!.items[2]!.value?.value).toBe('c');
});
Expand All @@ -44,9 +44,9 @@ describe('parseMultiSelectValue', function () {
expect(result!.items).toHaveLength(1);
const item = result!.items[0];

expect(item!.value!?.value).toBe('');
expect(item!.value!?.text).toBe('""');
expect(item!.value!?.quoted).toBe(true);
expect(item!.value?.value).toBe('');
expect(item!.value?.text).toBe('""');
expect(item!.value?.quoted).toBe(true);
});

it('single empty value', function () {
Expand All @@ -67,9 +67,9 @@ describe('parseMultiSelectValue', function () {

expect(result!.items).toHaveLength(3);

expect(result!?.items[0]!.value!?.value).toBe('a');
expect(result!?.items[1]!.value!?.value).toBe('');
expect(result!?.items[2]!.value!?.value).toBe('b');
expect(result?.items[0]!.value?.value).toBe('a');
expect(result?.items[1]!.value?.value).toBe('');
expect(result?.items[2]!.value?.value).toBe('b');
});

it('trailing comma', function () {
Expand All @@ -79,8 +79,8 @@ describe('parseMultiSelectValue', function () {

expect(result!.items).toHaveLength(2);

expect(result!?.items[0]!.value!?.value).toBe('a');
expect(result!?.items[1]!.value!?.value).toBe('');
expect(result?.items[0]!.value?.value).toBe('a');
expect(result?.items[1]!.value?.value).toBe('');
});

it('spaces', function () {
Expand All @@ -90,8 +90,8 @@ describe('parseMultiSelectValue', function () {

expect(result!.items).toHaveLength(3);

expect(result!?.items[0]!.value!?.value).toBe('a');
expect(result!?.items[1]!.value!?.value).toBe('b c');
expect(result!?.items[2]!.value!?.value).toBe('d');
expect(result?.items[0]!.value?.value).toBe('a');
expect(result?.items[1]!.value?.value).toBe('b c');
expect(result?.items[2]!.value?.value).toBe('d');
});
});
2 changes: 1 addition & 1 deletion static/app/utils/profiling/profile/jsSelfProfile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export class JSSelfProfile extends Profile {
}

const startedAt = profile.samples[0]!.timestamp;
const endedAt = profile.samples[profile.samples.length - 1]!?.timestamp;
const endedAt = profile.samples[profile.samples.length - 1]?.timestamp!;

const jsSelfProfile = new JSSelfProfile({
duration: endedAt - startedAt,
Expand Down
10 changes: 4 additions & 6 deletions static/app/utils/useExperiment.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,11 @@ export type UseExperiment = <E extends ExperimentKey>(
options?: UseExperimentOptions
) => UseExperimentReturnValue<E>;

const DEFAULT_RETURN_VALUE = {
experimentAssignment: unassignedValue,
logExperiment: noop,
};

export const useExperiment: UseExperiment = (...params) => {
return (
HookStore.get('react-hook:use-experiment')[0]!?.(...params) ?? DEFAULT_RETURN_VALUE
HookStore.get('react-hook:use-experiment')[0]?.(...params) ?? {
experimentAssignment: unassignedValue,
logExperiment: noop,
}
);
};
4 changes: 2 additions & 2 deletions static/app/utils/useMembers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,8 @@ async function fetchMembers(
const pageLinks = resp?.getResponseHeader('Link');
if (pageLinks) {
const paginationObject = parseLinkHeader(pageLinks);
hasMore = paginationObject?.next!?.results;
nextCursor = paginationObject?.next!?.cursor;
hasMore = paginationObject?.next?.results ?? null;
nextCursor = paginationObject?.next?.cursor ?? null;
}

return {results: data as Member[], hasMore, nextCursor};
Expand Down
5 changes: 3 additions & 2 deletions static/app/utils/useProjects.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,9 @@ async function fetchProjects(
const pageLinks = resp?.getResponseHeader('Link');
if (pageLinks) {
const paginationObject = parseLinkHeader(pageLinks);
hasMore = paginationObject?.next!?.results || paginationObject?.previous!?.results;
nextCursor = paginationObject?.next!?.cursor;
hasMore =
(paginationObject?.next?.results || paginationObject?.previous?.results) ?? null;
nextCursor = paginationObject?.next?.cursor ?? null;
}

return {results: data, hasMore, nextCursor};
Expand Down
4 changes: 2 additions & 2 deletions static/app/utils/useTeams.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,8 @@ async function fetchTeams(
const pageLinks = resp?.getResponseHeader('Link');
if (pageLinks) {
const paginationObject = parseLinkHeader(pageLinks);
hasMore = paginationObject?.next!?.results;
nextCursor = paginationObject?.next!?.cursor;
hasMore = paginationObject?.next?.results ?? null;
nextCursor = paginationObject?.next?.cursor ?? null;
}

return {results: data, hasMore, nextCursor};
Expand Down
6 changes: 3 additions & 3 deletions static/app/views/admin/adminOverview/eventChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,14 @@ class EventChart extends Component<Props, State> {

rawData['events.total']!.forEach((point, idx) => {
const dReceived = point![1];
const dRejected = rawData['events.dropped']![idx]!?.[1];
const dRejected = rawData['events.dropped']![idx]?.[1];
const ts = point![0]!;
if (sReceived[ts] === undefined) {
sReceived[ts] = dReceived;
sRejected[ts] = dRejected;
sRejected[ts] = dRejected!;
} else {
sReceived[ts] += dReceived;
sRejected[ts]! += dRejected;
sRejected[ts]! += dRejected!;
}
if (dReceived > 0) {
aReceived[0]! += dReceived;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ function SetupMessagingIntegrationButton({
return (
<IntegrationFeatures
organization={organization}
features={integrationProvidersQuery[0]!.data.providers[0]!?.metadata?.features}
features={integrationProvidersQuery[0]!.data.providers[0]?.metadata?.features!}
>
{({disabled, disabledReason}) => (
<div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,9 +218,9 @@ export function getMetricAlertChartOption({
) / ALERT_CHART_MIN_MAX_BUFFER
)
: 0;
const startDate = new Date(dataArr[0]!?.name);
const endDate =
dataArr.length > 1 ? new Date(dataArr[dataArr.length - 1]!?.name) : new Date();
const startDate = new Date(dataArr[0]?.name!);

const endDate = dataArr.length > 1 ? new Date(dataArr.at(-1)!.name) : new Date();
const firstPoint = startDate.getTime();
const lastPoint = endDate.getTime();
const totalDuration = lastPoint - firstPoint;
Expand All @@ -234,8 +234,8 @@ export function getMetricAlertChartOption({

if (showWaitingForData) {
const {startIndex, endIndex} = getWaitingForDataRange(dataArr);
const startTime = new Date(dataArr[startIndex]!?.name).getTime();
const endTime = new Date(dataArr[endIndex]!?.name).getTime();
const startTime = new Date(dataArr[startIndex]?.name!).getTime();
const endTime = new Date(dataArr[endIndex]?.name!).getTime();

waitingForDataDuration = Math.abs(endTime - startTime);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ class TriggersChart extends PureComponent<Props, State> {

const showExtrapolatedChartData =
shouldShowOnDemandMetricAlertUI(organization) &&
seriesAdditionalInfo?.[timeseriesData[0]!?.seriesName]?.isExtrapolatedData;
seriesAdditionalInfo?.[timeseriesData[0]?.seriesName!]?.isExtrapolatedData;

const totalCountLabel = isSessionAggregate(aggregate)
? // @ts-ignore TS(7053): Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ function WidgetBuilderSortBySelector() {
state.sort?.[0]?.kind === 'asc'
? SortDirection.LOW_TO_HIGH
: SortDirection.HIGH_TO_LOW,
sortBy: state.sort?.length ? state.sort?.[0]!?.field : '',
sortBy: state.sort?.length ? state.sort.at(0)!.field : '',
}}
onChange={({sortDirection, sortBy}) => {
const newSortDirection =
Expand Down
2 changes: 1 addition & 1 deletion static/app/views/dashboards/widgetCard/chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ class WidgetCardChart extends Component<WidgetCardChartProps> {

chartComponent(chartProps: any): React.ReactNode {
const {widget} = this.props;
const stacked = widget.queries[0]!?.columns.length > 0;
const stacked = widget.queries[0]?.columns.length! > 0;

switch (widget.displayType) {
case 'bar':
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ export const useTransactionWebVitalsScoresQuery = ({

const tableData: RowWithScoreAndOpportunity[] =
!isPending && data?.data.length
? data.data.map(row => {
? data.data.map<RowWithScoreAndOpportunity>(row => {
// Map back performance score key so we don't have to handle both keys in the UI
if (row['performance_score(measurements.score.total)'] !== undefined) {
row['avg(measurements.score.total)'] =
Expand All @@ -126,8 +126,8 @@ export const useTransactionWebVitalsScoresQuery = ({
const {totalScore, clsScore, fcpScore, lcpScore, ttfbScore, inpScore} =
getWebVitalScoresFromTableDataRow(row);
return {
transaction: row.transaction!?.toString(),
project: row.project!?.toString(),
transaction: row.transaction?.toString()!,
project: row.project?.toString()!,
'project.id': parseInt(row['project.id']!.toString(), 10),
'p75(measurements.lcp)': row['p75(measurements.lcp)'] as number,
'p75(measurements.fcp)': row['p75(measurements.fcp)'] as number,
Expand Down
6 changes: 3 additions & 3 deletions static/app/views/insights/cache/components/samplePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ export function CacheSamplePanel() {
value={cacheTransactionMetrics?.[0]?.['sum(span.self_time)']}
unit={DurationUnit.MILLISECOND}
tooltip={getTimeSpentExplanation(
cacheTransactionMetrics?.[0]!?.['time_spent_percentage()']
cacheTransactionMetrics?.[0]?.['time_spent_percentage()']!
)}
isLoading={areCacheTransactionMetricsFetching}
/>
Expand All @@ -311,9 +311,9 @@ export function CacheSamplePanel() {
<TransactionDurationChart
samples={spansWithDuration}
averageTransactionDuration={
transactionDurationData?.[0]!?.[
transactionDurationData?.[0]?.[
`avg(${MetricsFields.TRANSACTION_DURATION})`
]
]!
}
highlightedSpanId={highlightedSpanId}
onHighlight={highlights => {
Expand Down
6 changes: 3 additions & 3 deletions static/app/views/insights/common/components/chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -227,10 +227,10 @@ function Chart({
let incompleteSeries: Series[] = [];

const bucketSize =
new Date(series[0]!?.data[1]!?.name).getTime() -
new Date(series[0]!?.data[0]!?.name).getTime();
new Date(series[0]?.data[1]?.name!).getTime() -
new Date(series[0]?.data[0]?.name!).getTime();
const lastBucketTimestamp = new Date(
series[0]!?.data?.[series[0]!?.data?.length - 1]!?.name
series[0]?.data?.[series[0]?.data?.length - 1]?.name!
).getTime();
const ingestionBuckets = useMemo(() => {
if (isNaN(bucketSize) || isNaN(lastBucketTimestamp)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ export function HTTPSamplesPanel() {
value={domainTransactionMetrics?.[0]?.['sum(span.self_time)']}
unit={DurationUnit.MILLISECOND}
tooltip={getTimeSpentExplanation(
domainTransactionMetrics?.[0]!?.['time_spent_percentage()'],
domainTransactionMetrics?.[0]?.['time_spent_percentage()']!,
'http.client'
)}
isLoading={areDomainTransactionMetricsFetching}
Expand Down
Loading
Loading