mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Chore: Type improvements 🧹 (#75271)
* fix some e2e flows types * some type fixes * must... fix... more... * MOAR * MOREMOREMORE * 1 more
This commit is contained in:
@@ -50,6 +50,7 @@ export function compareDataFrameStructures(a: DataFrame, b: DataFrame, skipConfi
|
||||
// see e.g. https://github.com/Microsoft/TypeScript/issues/12870
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||
let aKeys = Object.keys(cfgA) as Array<keyof typeof cfgA>;
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||
let bKeys = Object.keys(cfgB) as Array<keyof typeof cfgB>;
|
||||
|
||||
if (aKeys.length !== bKeys.length) {
|
||||
|
||||
@@ -120,14 +120,14 @@ const mapInternal = (zone: string, timestamp: number): TimeZoneInfo | undefined
|
||||
case InternalTimeZones.default: {
|
||||
const tz = getTimeZone();
|
||||
const isInternal = tz === 'browser' || tz === 'utc';
|
||||
const info = (isInternal ? mapInternal(tz, timestamp) : mapToInfo(tz, timestamp)) ?? {};
|
||||
const info = isInternal ? mapInternal(tz, timestamp) : mapToInfo(tz, timestamp);
|
||||
|
||||
return {
|
||||
countries: countriesByTimeZone[tz] ?? [],
|
||||
abbreviation: '',
|
||||
offsetInMins: 0,
|
||||
...info,
|
||||
ianaName: (info as TimeZoneInfo).ianaName,
|
||||
ianaName: info?.ianaName ?? '',
|
||||
name: 'Default',
|
||||
zone,
|
||||
};
|
||||
@@ -135,7 +135,7 @@ const mapInternal = (zone: string, timestamp: number): TimeZoneInfo | undefined
|
||||
|
||||
case InternalTimeZones.localBrowserTime: {
|
||||
const tz = moment.tz.guess(true);
|
||||
const info = mapToInfo(tz, timestamp) ?? {};
|
||||
const info = mapToInfo(tz, timestamp);
|
||||
|
||||
return {
|
||||
countries: countriesByTimeZone[tz] ?? [],
|
||||
@@ -143,7 +143,7 @@ const mapInternal = (zone: string, timestamp: number): TimeZoneInfo | undefined
|
||||
offsetInMins: new Date().getTimezoneOffset(),
|
||||
...info,
|
||||
name: 'Browser Time',
|
||||
ianaName: (info as TimeZoneInfo).ianaName,
|
||||
ianaName: info?.ianaName ?? '',
|
||||
zone,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -123,20 +123,20 @@ class ScopedEventBus implements EventBus {
|
||||
|
||||
publish<T extends BusEvent>(event: T): void {
|
||||
if (!event.origin) {
|
||||
(event as any).origin = this;
|
||||
event.origin = this;
|
||||
}
|
||||
this.eventBus.publish(event);
|
||||
}
|
||||
|
||||
filter = (event: BusEvent) => {
|
||||
filter<T extends BusEvent>(event: T) {
|
||||
if (this.filterConfig.onlyLocal) {
|
||||
return event.origin === this;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
getStream<T extends BusEvent>(eventType: BusEventType<T>): Observable<T> {
|
||||
return this.eventBus.getStream(eventType).pipe(filter(this.filter)) as Observable<T>;
|
||||
return this.eventBus.getStream(eventType).pipe(filter(this.filter));
|
||||
}
|
||||
|
||||
// syntax sugar
|
||||
|
||||
@@ -7,7 +7,7 @@ import { Unsubscribable, Observable } from 'rxjs';
|
||||
export interface BusEvent {
|
||||
readonly type: string;
|
||||
readonly payload?: any;
|
||||
readonly origin?: EventBus;
|
||||
origin?: EventBus;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,7 +18,9 @@ export function findHighlightChunksInText({
|
||||
}) {
|
||||
const chunks: TextMatch[] = [];
|
||||
for (const term of searchWords) {
|
||||
chunks.push(...findMatchesInText(textToHighlight, term as string));
|
||||
if (typeof term === 'string') {
|
||||
chunks.push(...findMatchesInText(textToHighlight, term));
|
||||
}
|
||||
}
|
||||
return chunks;
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ export interface CalculateFieldTransformerOptions {
|
||||
// TODO: config?: FieldConfig; or maybe field overrides? since the UI exists
|
||||
}
|
||||
|
||||
type ValuesCreator = (data: DataFrame) => any[];
|
||||
type ValuesCreator = (data: DataFrame) => unknown[] | undefined;
|
||||
|
||||
export const calculateFieldTransformer: DataTransformerInfo<CalculateFieldTransformerOptions> = {
|
||||
id: DataTransformerID.calculateField,
|
||||
@@ -178,7 +178,7 @@ function getReduceRowCreator(options: ReduceOptions, allFrames: DataFrame[]): Va
|
||||
|
||||
return (frame: DataFrame) => {
|
||||
// Find the columns that should be examined
|
||||
const columns: any[] = [];
|
||||
const columns = [];
|
||||
for (const field of frame.fields) {
|
||||
if (matcher(field, frame, allFrames)) {
|
||||
columns.push(field.values);
|
||||
@@ -239,7 +239,7 @@ function getBinaryCreator(options: BinaryOptions, allFrames: DataFrame[]): Value
|
||||
const left = findFieldValuesWithNameOrConstant(frame, options.left, allFrames);
|
||||
const right = findFieldValuesWithNameOrConstant(frame, options.right, allFrames);
|
||||
if (!left || !right || !operator) {
|
||||
return undefined as unknown as any[];
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const arr = new Array(left.length);
|
||||
|
||||
@@ -253,7 +253,7 @@ export function buildHistogram(frames: DataFrame[], options?: HistogramTransform
|
||||
for (const frame of frames) {
|
||||
for (const field of frame.fields) {
|
||||
if (field.type === FieldType.number) {
|
||||
let fieldHist = histogram(field.values, getBucket, histFilter, histSort) as AlignedData;
|
||||
let fieldHist = histogram(field.values, getBucket, histFilter, histSort);
|
||||
histograms.push(fieldHist);
|
||||
counts.push({
|
||||
...field,
|
||||
@@ -362,7 +362,7 @@ function histogram(
|
||||
getBucket: (v: number) => number,
|
||||
filterOut?: any[] | null,
|
||||
sort?: ((a: number, b: number) => number) | null
|
||||
) {
|
||||
): AlignedData {
|
||||
let hist = new Map();
|
||||
|
||||
for (let i = 0; i < vals.length; i++) {
|
||||
|
||||
@@ -157,9 +157,7 @@ export const hasLogsContextSupport = (datasource: unknown): datasource is DataSo
|
||||
return false;
|
||||
}
|
||||
|
||||
const withLogsSupport = datasource as DataSourceWithLogsContextSupport;
|
||||
|
||||
return withLogsSupport.getLogRowContext !== undefined && withLogsSupport.showContextToggle !== undefined;
|
||||
return 'getLogRowContext' in datasource && 'showContextToggle' in datasource;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -259,9 +257,7 @@ export const hasLogsContextUiSupport = (datasource: unknown): datasource is Data
|
||||
return false;
|
||||
}
|
||||
|
||||
const withLogsSupport = datasource as DataSourceWithLogsContextSupport;
|
||||
|
||||
return withLogsSupport.getLogRowContextUi !== undefined;
|
||||
return 'getLogRowContextUi' in datasource;
|
||||
};
|
||||
|
||||
export interface QueryFilterOptions extends KeyValue<string> {}
|
||||
|
||||
@@ -66,7 +66,10 @@ export interface DataSourceWithQueryExportSupport<TQuery extends SchemaDataQuery
|
||||
export const hasQueryImportSupport = <TQuery extends SchemaDataQuery>(
|
||||
datasource: unknown
|
||||
): datasource is DataSourceWithQueryImportSupport<TQuery> => {
|
||||
return (datasource as DataSourceWithQueryImportSupport<TQuery>).importFromAbstractQueries !== undefined;
|
||||
if (!datasource) {
|
||||
return false;
|
||||
}
|
||||
return 'importFromAbstractQueries' in datasource;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -75,5 +78,8 @@ export const hasQueryImportSupport = <TQuery extends SchemaDataQuery>(
|
||||
export const hasQueryExportSupport = <TQuery extends SchemaDataQuery>(
|
||||
datasource: unknown
|
||||
): datasource is DataSourceWithQueryExportSupport<TQuery> => {
|
||||
return (datasource as DataSourceWithQueryExportSupport<TQuery>).exportToAbstractQueries !== undefined;
|
||||
if (!datasource) {
|
||||
return false;
|
||||
}
|
||||
return 'exportToAbstractQueries' in datasource;
|
||||
};
|
||||
|
||||
@@ -16,24 +16,24 @@ declare global {
|
||||
if (!Object.getOwnPropertyDescriptor(Array.prototype, 'toArray')) {
|
||||
Object.defineProperties(Array.prototype, {
|
||||
get: {
|
||||
value: function (idx: number): any {
|
||||
return (this as any)[idx];
|
||||
value: function (idx: number) {
|
||||
return this[idx];
|
||||
},
|
||||
writable: true,
|
||||
enumerable: false,
|
||||
configurable: true,
|
||||
},
|
||||
set: {
|
||||
value: function (idx: number, value: any) {
|
||||
(this as any)[idx] = value;
|
||||
value: function (idx: number, value: unknown) {
|
||||
this[idx] = value;
|
||||
},
|
||||
writable: true,
|
||||
enumerable: false,
|
||||
configurable: true,
|
||||
},
|
||||
add: {
|
||||
value: function (value: any) {
|
||||
(this as any).push(value);
|
||||
value: function (value: unknown) {
|
||||
this.push(value);
|
||||
},
|
||||
writable: true,
|
||||
enumerable: false,
|
||||
@@ -106,7 +106,7 @@ export interface MutableVector<T = any> extends ReadWriteVector<T> {}
|
||||
* @deprecated
|
||||
*/
|
||||
export function makeArrayIndexableVector<T extends Vector>(v: T): T {
|
||||
return new Proxy(v, {
|
||||
return new Proxy<T>(v, {
|
||||
get(target: Vector, property: string, receiver: Vector) {
|
||||
if (typeof property !== 'symbol') {
|
||||
const idx = +property;
|
||||
@@ -116,7 +116,7 @@ export function makeArrayIndexableVector<T extends Vector>(v: T): T {
|
||||
}
|
||||
return Reflect.get(target, property, receiver);
|
||||
},
|
||||
set(target: Vector, property: string, value: any, receiver: Vector) {
|
||||
set(target: Vector, property: string, value: unknown, receiver: Vector) {
|
||||
if (typeof property !== 'symbol') {
|
||||
const idx = +property;
|
||||
if (String(idx) === property) {
|
||||
@@ -126,5 +126,5 @@ export function makeArrayIndexableVector<T extends Vector>(v: T): T {
|
||||
}
|
||||
return Reflect.set(target, property, value, receiver);
|
||||
},
|
||||
}) as T;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ export function getValueMappingResult(valueMappings: ValueMapping[], value: any)
|
||||
continue;
|
||||
}
|
||||
|
||||
const valueAsNumber = parseFloat(value as string);
|
||||
const valueAsNumber = parseFloat(value);
|
||||
if (isNaN(valueAsNumber)) {
|
||||
continue;
|
||||
}
|
||||
@@ -76,13 +76,13 @@ export function getValueMappingResult(valueMappings: ValueMapping[], value: any)
|
||||
break;
|
||||
}
|
||||
case SpecialValueMatch.NaN: {
|
||||
if (isNaN(value as number)) {
|
||||
if (typeof value === 'number' && isNaN(value)) {
|
||||
return vm.options.result;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SpecialValueMatch.NullAndNaN: {
|
||||
if (isNaN(value as number) || value == null) {
|
||||
if ((typeof value === 'number' && isNaN(value)) || value == null) {
|
||||
return vm.options.result;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -29,7 +29,7 @@ export function getRefField(frame: DataFrame, refFieldName?: string | null) {
|
||||
function applySpanNullsThresholds(frame: DataFrame, refFieldName?: string | null) {
|
||||
const refField = getRefField(frame, refFieldName);
|
||||
|
||||
let refValues = refField?.values as any[];
|
||||
let refValues = refField?.values;
|
||||
|
||||
for (let i = 0; i < frame.fields.length; i++) {
|
||||
let field = frame.fields[i];
|
||||
@@ -41,7 +41,7 @@ function applySpanNullsThresholds(frame: DataFrame, refFieldName?: string | null
|
||||
let spanNulls = field.config.custom?.spanNulls;
|
||||
|
||||
if (typeof spanNulls === 'number') {
|
||||
if (spanNulls !== -1) {
|
||||
if (spanNulls !== -1 && refValues) {
|
||||
field.values = nullToUndefThreshold(refValues, field.values, spanNulls);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,7 +103,11 @@ export function cssClass(className: string): string {
|
||||
* Creates a new DOM element with given type and class
|
||||
* TODO: move me to helpers
|
||||
*/
|
||||
export function createElement(type: string, className?: string, content?: Element | string): Element {
|
||||
export function createElement<T extends keyof HTMLElementTagNameMap>(
|
||||
type: T,
|
||||
className?: string,
|
||||
content?: Element | string
|
||||
) {
|
||||
const el = document.createElement(type);
|
||||
if (className) {
|
||||
el.classList.add(cssClass(className));
|
||||
|
||||
@@ -42,7 +42,7 @@ export class JsonExplorer {
|
||||
private _isOpen: boolean | null = null;
|
||||
|
||||
// A reference to the element that we render to
|
||||
private element: Element | null = null;
|
||||
private element: HTMLDivElement | null = null;
|
||||
|
||||
private skipChildren = false;
|
||||
|
||||
@@ -358,7 +358,7 @@ export class JsonExplorer {
|
||||
togglerLink.addEventListener('click', this.toggleOpen.bind(this));
|
||||
}
|
||||
|
||||
return this.element as HTMLDivElement;
|
||||
return this.element;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -404,8 +404,7 @@ export class JsonExplorer {
|
||||
* Animated option is used when user triggers this via a click
|
||||
*/
|
||||
removeChildren(animated = false) {
|
||||
const childrenElement =
|
||||
this.element && (this.element.querySelector(`div.${cssClass('children')}`) as HTMLDivElement);
|
||||
const childrenElement = this.element && this.element.querySelector<HTMLDivElement>(`div.${cssClass('children')}`);
|
||||
|
||||
if (animated) {
|
||||
let childrenRemoved = 0;
|
||||
|
||||
@@ -236,7 +236,7 @@ export function sharedSingleStatMigrationHandler(panel: PanelModel<SingleStatBas
|
||||
}
|
||||
}
|
||||
|
||||
return options as SingleStatBaseOptions;
|
||||
return options;
|
||||
}
|
||||
|
||||
export function moveThresholdsAndMappingsToField(old: any) {
|
||||
|
||||
@@ -19,7 +19,7 @@ export interface Props {
|
||||
}
|
||||
|
||||
export function ExpandedRow({ tableStyles, nestedData, rowIndex, width, cellHeight }: Props) {
|
||||
const frames = nestedData.values as DataFrame[][];
|
||||
const frames: DataFrame[][] = nestedData.values;
|
||||
const subTables: React.ReactNode[] = [];
|
||||
const theme = useTheme2();
|
||||
const styles = useStyles2(getStyles);
|
||||
@@ -72,7 +72,7 @@ const getStyles = (theme: GrafanaTheme2) => {
|
||||
};
|
||||
|
||||
export function getExpandedRowHeight(nestedData: Field, rowIndex: number, tableStyles: TableStyles) {
|
||||
const frames = nestedData.values as DataFrame[][];
|
||||
const frames: DataFrame[][] = nestedData.values;
|
||||
|
||||
const height = frames[rowIndex].reduce((acc: number, frame: DataFrame) => {
|
||||
if (frame.length) {
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
} from 'react-table';
|
||||
import { VariableSizeList } from 'react-window';
|
||||
|
||||
import { Field, FieldType, ReducerID } from '@grafana/data';
|
||||
import { FieldType, ReducerID } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { TableCellHeight } from '@grafana/schema';
|
||||
|
||||
@@ -176,7 +176,7 @@ export const Table = memo((props: Props) => {
|
||||
}
|
||||
|
||||
const footerItems = getFooterItems(
|
||||
headerGroups[0].headers as unknown as Array<{ id: string; field: Field }>,
|
||||
headerGroups[0].headers,
|
||||
createFooterCalculationValues(rows),
|
||||
footerOptions,
|
||||
theme
|
||||
|
||||
@@ -30,16 +30,20 @@ export const TableCell = ({ cell, tableStyles, onCellFilterAdded, timeRange, use
|
||||
cellProps.style.justifyContent = (cell.column as any).justifyContent;
|
||||
}
|
||||
|
||||
let innerWidth = ((cell.column.width as number) ?? 24) - tableStyles.cellPadding * 2;
|
||||
let innerWidth = (typeof cell.column.width === 'number' ? cell.column.width : 24) - tableStyles.cellPadding * 2;
|
||||
|
||||
return cell.render('Cell', {
|
||||
field,
|
||||
tableStyles,
|
||||
onCellFilterAdded,
|
||||
cellProps,
|
||||
innerWidth,
|
||||
timeRange,
|
||||
userProps,
|
||||
frame,
|
||||
}) as React.ReactElement;
|
||||
return (
|
||||
<>
|
||||
{cell.render('Cell', {
|
||||
field,
|
||||
tableStyles,
|
||||
onCellFilterAdded,
|
||||
cellProps,
|
||||
innerWidth,
|
||||
timeRange,
|
||||
userProps,
|
||||
frame,
|
||||
})}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -49,7 +49,7 @@ export function getTextAlign(field?: Field): Property.JustifyContent {
|
||||
}
|
||||
|
||||
if (field.config.custom) {
|
||||
const custom = field.config.custom as TableFieldOptions;
|
||||
const custom: TableFieldOptions = field.config.custom;
|
||||
|
||||
switch (custom.align) {
|
||||
case 'right':
|
||||
@@ -101,7 +101,7 @@ export function getColumns(
|
||||
}
|
||||
|
||||
for (const [fieldIndex, field] of data.fields.entries()) {
|
||||
const fieldTableOptions = (field.config.custom || {}) as TableFieldOptions;
|
||||
const fieldTableOptions: TableFieldOptions = field.config.custom || {};
|
||||
if (fieldTableOptions.hidden || field.type === FieldType.nestedFrames) {
|
||||
continue;
|
||||
}
|
||||
@@ -131,7 +131,7 @@ export function getColumns(
|
||||
id: fieldIndex.toString(),
|
||||
field: field,
|
||||
Header: fieldTableOptions.hideHeader ? '' : getFieldDisplayName(field, data),
|
||||
accessor: (_row: any, i: number) => {
|
||||
accessor: (_row, i) => {
|
||||
return field.values[i];
|
||||
},
|
||||
sortType: selectSortType(field.type),
|
||||
@@ -255,7 +255,7 @@ export function rowToFieldValue(row: any, field?: Field): string {
|
||||
return value;
|
||||
}
|
||||
|
||||
export function valuesToOptions(unique: Record<string, any>): SelectableValue[] {
|
||||
export function valuesToOptions(unique: Record<string, unknown>): SelectableValue[] {
|
||||
return Object.keys(unique)
|
||||
.reduce<SelectableValue[]>((all, key) => all.concat({ value: unique[key], label: key }), [])
|
||||
.sort(sortOptions);
|
||||
@@ -293,12 +293,12 @@ export function getFilteredOptions(options: SelectableValue[], filterValues?: Se
|
||||
return options.filter((option) => filterValues.some((filtered) => filtered.value === option.value));
|
||||
}
|
||||
|
||||
export function sortCaseInsensitive(a: Row<any>, b: Row<any>, id: string) {
|
||||
export function sortCaseInsensitive(a: Row, b: Row, id: string) {
|
||||
return String(a.values[id]).localeCompare(String(b.values[id]), undefined, { sensitivity: 'base' });
|
||||
}
|
||||
|
||||
// sortNumber needs to have great performance as it is called a lot
|
||||
export function sortNumber(rowA: Row<any>, rowB: Row<any>, id: string) {
|
||||
export function sortNumber(rowA: Row, rowB: Row, id: string) {
|
||||
const a = toNumber(rowA.values[id]);
|
||||
const b = toNumber(rowB.values[id]);
|
||||
return a === b ? 0 : a > b ? 1 : -1;
|
||||
|
||||
@@ -118,11 +118,11 @@ export function getStackingGroups(frame: DataFrame) {
|
||||
let stackDir = getStackDirection(transform, values);
|
||||
|
||||
let drawStyle: GraphDrawStyle = custom.drawStyle;
|
||||
let drawStyle2 =
|
||||
let drawStyle2: BarAlignment | LineInterpolation | null =
|
||||
drawStyle === GraphDrawStyle.Bars
|
||||
? (custom.barAlignment as BarAlignment)
|
||||
? custom.barAlignment
|
||||
: drawStyle === GraphDrawStyle.Line
|
||||
? (custom.lineInterpolation as LineInterpolation)
|
||||
? custom.lineInterpolation
|
||||
: null;
|
||||
|
||||
let stackKey = `${stackDir}|${stackingMode}|${stackingGroup}|${buildScaleKey(
|
||||
|
||||
Reference in New Issue
Block a user