kibana/x-pack/plugins/security_solution/public/common/components/utils.ts
Kibana Machine d2075f63d2
[Security solutions] Adds linter rule to forbid usage of no-non-null-assertion (TypeScript ! bang operator) (#114375) (#115126)
## Summary

Fixes: https://github.com/elastic/kibana/issues/114535

**What this linter rule does:**
* Sets the [@typescript-eslint/no-non-null-assertion](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-non-null-assertion.md) linter rule to become an error if seen.

If you try to use the `!` operator you get an error and nice helper message that tries to encourage better practices such as this one:

<img width="1635" alt="Screen Shot 2021-10-07 at 11 26 14 AM" src="https://user-images.githubusercontent.com/1151048/136474207-f38d3461-0af9-4cdc-885b-632cb49d8a24.png">

**Why are we deciding to set this linter rule?**
* Recommended from Kibana [styleguide](https://github.com/elastic/kibana/blob/master/STYLEGUIDE.mdx#avoid-non-null-assertions) for ~2 years now and still recommended.
* A lot of TypeScript has evolved and has operators such as `?` which can replace the `!` in most cases. Other cases can use a throw explicitly or other ways to manage this.
* Some types can change instead of using this operator and we should just change the types.
* TypeScript flows have improved and when we upgrade the linter will cause errors where we can remove the `!` operator which is 👍 better than leaving them when they're not needed anymore.
* Newer programmers and team members sometimes mistake it for the `?` when it is not the same thing.
* We have had past bugs and bugs recently because of these.
* It's easier to use the linter to find bugs than to rely on manual tests. 

**How did Frank fix all the 403 areas in which the linter goes off?**
* Anywhere I could remove the `!` operator without side effects or type script errors I just removed the `!` operator.
* Anywhere in test code where I could replace the code with a `?` or a `throw` I went through that route.
* Within the code areas (non test code) where I saw what looks like a simple bug that I could fix using a `?? []` or `?` operator or `String(value)` or fixing a simple type I would choose that route first. These areas I marked in the code review with the words `NOTE:` for anyone to look at.
* Within all other areas of the code and tests where anything looked more involved I just disabled the linter for that particular line. When in doubt I chose this route.

### Checklist

- [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios

Co-authored-by: Frank Hassanabad <frank.hassanabad@elastic.co>
2021-10-15 01:01:23 -04:00

37 lines
1.4 KiB
TypeScript

/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { throttle } from 'lodash/fp';
import { useMemo, useState } from 'react';
import useResizeObserver from 'use-resize-observer/polyfilled';
import { niceTimeFormatByDay, timeFormatter } from '@elastic/charts';
import moment from 'moment-timezone';
export const getDaysDiff = (minDate: moment.Moment, maxDate: moment.Moment) => {
const diff = maxDate.diff(minDate, 'days');
if (diff <= 1 && !minDate.isSame(maxDate)) {
return 2; // to return proper pattern from niceTimeFormatByDay
}
return diff;
};
export const histogramDateTimeFormatter = (domain: [string, string] | null, fixedDiff?: number) => {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const diff = fixedDiff ?? getDaysDiff(moment(domain![0]), moment(domain![1]));
const format = niceTimeFormatByDay(diff);
return timeFormatter(format);
};
export const useThrottledResizeObserver = (wait = 100) => {
const [size, setSize] = useState<{ width: number; height: number }>({ width: 0, height: 0 });
const onResize = useMemo(() => throttle(wait, setSize), [wait]);
const { ref } = useResizeObserver<HTMLDivElement>({ onResize });
return { ref, ...size };
};