From 50d594787c93c897e832f0742c77191d1c5e02b4 Mon Sep 17 00:00:00 2001 From: Ken <26967723+KenAJoh@users.noreply.github.com> Date: Mon, 27 May 2024 14:05:07 +0200 Subject: [PATCH] Disallow use of implicit any type on variable declarations. (#2943) * feat: Added biome again * bug: Fixes Disallow use of implicit any type on variable declarations. * refactor: Import as type * refactor: Reverted change to typed for-loops in dialog-polyfill * refactor: Reverted change to typed for-loops in dialog-polyfill * Update @navikt/core/react/src/modal/dialog-polyfill.ts Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com> * refactor: biome-ignored inline-typing for-loop --------- Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com> --- .../core/react/src/date/utils/navigation.ts | 6 +- .../core/react/src/date/utils/parse-date.ts | 11 +- .../filteredOptionsContext.tsx | 3 +- .../core/react/src/modal/dialog-polyfill.ts | 5 +- .../tabs/parts/tablist/useScrollButtons.ts | 4 +- @navikt/core/react/src/util/debounce.ts | 2 +- .../search/__tests__/group-results.test.ts | 113 ++++++++++-------- .../providers/SearchNavigationProvider.tsx | 2 +- biome.json | 1 - 9 files changed, 85 insertions(+), 62 deletions(-) diff --git a/@navikt/core/react/src/date/utils/navigation.ts b/@navikt/core/react/src/date/utils/navigation.ts index f44e71bfa0..894409c168 100644 --- a/@navikt/core/react/src/date/utils/navigation.ts +++ b/@navikt/core/react/src/date/utils/navigation.ts @@ -2,7 +2,7 @@ import { setYear } from "date-fns"; import { Matcher, isMatch } from "./is-match"; export const nextEnabled = ( - months, + months: Date[], key: string, disabled: Matcher[], currentMonth: Date, @@ -258,13 +258,13 @@ const isOutOfRange = ( const nextOnRow = ( currentIndex: number, - months, + months: Date[], yearState: Date, disabled: Matcher[], mode: "home" | "end", ) => { const row = getRow(currentIndex); - let monthsOfRow; + let monthsOfRow: Date[] = []; switch (row) { case 1: diff --git a/@navikt/core/react/src/date/utils/parse-date.ts b/@navikt/core/react/src/date/utils/parse-date.ts index ae27e8b522..b2657e402b 100644 --- a/@navikt/core/react/src/date/utils/parse-date.ts +++ b/@navikt/core/react/src/date/utils/parse-date.ts @@ -29,7 +29,7 @@ export const parseDate = ( type: "date" | "month", allowTwoDigitYear: boolean, ): Date => { - let parsed; + let parsed: Date; const ALLOWED_FORMATS = type === "date" ? ALLOWED_INPUT_FORMATS_DATE : ALLOWED_INPUT_FORMATS_MONTH; @@ -76,8 +76,13 @@ export const parseDate = ( return new Date("Invalid date"); }; -function isTwoDigitYear(dateString, today, locale, formats) { - let parsed; +function isTwoDigitYear( + dateString: string, + today: Date, + locale: Locale, + formats: string[], +) { + let parsed: Date; const newFormat = formats.map((x) => x.replace("yyyy", "yy")); for (const format of newFormat) { parsed = parse(dateString, format, today, { locale }); diff --git a/@navikt/core/react/src/form/combobox/FilteredOptions/filteredOptionsContext.tsx b/@navikt/core/react/src/form/combobox/FilteredOptions/filteredOptionsContext.tsx index 49250eeb3b..e232088c78 100644 --- a/@navikt/core/react/src/form/combobox/FilteredOptions/filteredOptionsContext.tsx +++ b/@navikt/core/react/src/form/combobox/FilteredOptions/filteredOptionsContext.tsx @@ -146,7 +146,7 @@ const FilteredOptionsProvider = ({ ); const ariaDescribedBy = useMemo(() => { - let activeOption; + let activeOption: string = ""; if (!isLoading && filteredOptions.length === 0 && !allowNewValues) { activeOption = filteredOptionsUtils.getNoHitsId(id); } else if (value || isLoading) { @@ -162,6 +162,7 @@ const FilteredOptionsProvider = ({ const maybeMaxSelectedOptionsId = maxSelected?.isLimitReached && filteredOptionsUtils.getMaxSelectedOptionsId(id); + return ( cl(activeOption, maybeMaxSelectedOptionsId, partialAriaDescribedBy) || undefined diff --git a/@navikt/core/react/src/modal/dialog-polyfill.ts b/@navikt/core/react/src/modal/dialog-polyfill.ts index 0f408bc001..04faaa9854 100644 --- a/@navikt/core/react/src/modal/dialog-polyfill.ts +++ b/@navikt/core/react/src/modal/dialog-polyfill.ts @@ -260,7 +260,7 @@ function dialogPolyfillInfo(dialog) { removed ? this.downgradeModal() : this.maybeHideModal(); removed = false; }.bind(this); - var timeout; + var timeout: ReturnType; var delayModel = function (ev) { if (ev.target !== dialog) { return; @@ -631,6 +631,7 @@ dialogPolyfill.DialogManager = function () { this.mo_ = new MutationObserver(function (records) { var removed = []; records.forEach(function (rec) { + // biome-ignore lint/suspicious/noImplicitAnyLet: Reduntant to type c in this scenario for (var i = 0, c; (c = rec.removedNodes[i]); ++i) { if (!(c instanceof Element)) { continue; @@ -678,6 +679,7 @@ dialogPolyfill.DialogManager.prototype.unblockDocument = function () { dialogPolyfill.DialogManager.prototype.updateStacking = function () { var zIndex = this.zIndexHigh_; + // biome-ignore lint/suspicious/noImplicitAnyLet: Reduntant to type dpi in this scenario for (var i = 0, dpi; (dpi = this.pendingDialogStack[i]); ++i) { dpi.updateZIndex(--zIndex, --zIndex); if (i === 0) { @@ -703,6 +705,7 @@ dialogPolyfill.DialogManager.prototype.containedByTopDialog_ = function ( candidate, ) { while ((candidate = findNearestDialog(candidate))) { + // biome-ignore lint/suspicious/noImplicitAnyLet: Reduntant to type dpi in this scenario for (var i = 0, dpi; (dpi = this.pendingDialogStack[i]); ++i) { if (dpi.dialog === candidate) { return i === 0; // only valid if top-most diff --git a/@navikt/core/react/src/tabs/parts/tablist/useScrollButtons.ts b/@navikt/core/react/src/tabs/parts/tablist/useScrollButtons.ts index 9c60087bab..f757635a66 100644 --- a/@navikt/core/react/src/tabs/parts/tablist/useScrollButtons.ts +++ b/@navikt/core/react/src/tabs/parts/tablist/useScrollButtons.ts @@ -32,9 +32,9 @@ export function useScrollButtons(listRef: React.RefObject) { const win = listRef.current?.ownerDocument ?? document ?? window; win.addEventListener("resize", handleResize); - let resizeObserver; + let resizeObserver: ResizeObserver; - if (typeof ResizeObserver !== "undefined") { + if (typeof ResizeObserver !== "undefined" && listRef.current) { resizeObserver = new ResizeObserver(handleResize); resizeObserver.observe(listRef.current); } diff --git a/@navikt/core/react/src/util/debounce.ts b/@navikt/core/react/src/util/debounce.ts index 3b6d4020ff..743b151c93 100644 --- a/@navikt/core/react/src/util/debounce.ts +++ b/@navikt/core/react/src/util/debounce.ts @@ -1,7 +1,7 @@ "use client"; // https://github.com/mui/material-ui/blob/master/packages/mui-utils/src/debounce.js export default function debounce(func, wait = 166) { - let timeout; + let timeout: ReturnType; function debounced(this: any, ...args) { const later = () => { func.apply(this, args); diff --git a/aksel.nav.no/website/components/website-modules/search/__tests__/group-results.test.ts b/aksel.nav.no/website/components/website-modules/search/__tests__/group-results.test.ts index 405dcf159c..e190f82b92 100644 --- a/aksel.nav.no/website/components/website-modules/search/__tests__/group-results.test.ts +++ b/aksel.nav.no/website/components/website-modules/search/__tests__/group-results.test.ts @@ -1,73 +1,84 @@ +import { FuseResult } from "fuse.js"; import { beforeEach, describe, expect, test } from "vitest"; -import { SearchResultsT } from "@/types"; +import type { FuseItemT, SearchHitT, SearchResultsT } from "@/types"; import { createSearchResult } from "../utils"; describe("createSearchResult", () => { - let result; - let rawResults; + let result: SearchHitT[]; + let rawResults: FuseResult[]; + + const placeholders = { heading: "", slug: "", content: [] }; beforeEach(() => { - result = [ - { - item: { _type: "komponent_artikkel" }, - score: 0.05, - matches: [], - }, - { - item: { _type: "aksel_artikkel" }, - score: 0.1, - matches: [], - }, - { - item: { _type: "ds_artikkel" }, - score: 0.15, - matches: [], - }, - { - item: { _type: "aksel_blogg" }, - score: 0.2, - matches: [], - }, - { - item: { _type: "aksel_prinsipp" }, - score: 0.25, - matches: [], - }, - { - item: { _type: "aksel_standalone" }, - score: 0.3, - matches: [], + const items = { + komponent_artikkel: { score: 0.05 }, + aksel_artikkel: { score: 0.1 }, + ds_artikkel: { score: 0.15 }, + aksel_blogg: { score: 0.2 }, + aksel_prinsipp: { score: 0.25 }, + aksel_standalone: { score: 0.3 }, + }; + + result = Object.entries(items).map(([key, value]) => ({ + item: { + _type: key as keyof typeof items, + ...placeholders, }, - ]; - rawResults = [ - { item: { _type: "komponent_artikkel" }, score: 0.05 }, - { item: { _type: "aksel_artikkel" }, score: 0.1 }, - { item: { _type: "ds_artikkel" }, score: 0.15 }, - { item: { _type: "aksel_blogg" }, score: 0.2 }, - { item: { _type: "aksel_prinsipp" }, score: 0.25 }, - { item: { _type: "aksel_standalone" }, score: 0.3 }, - ]; + score: value.score, + matches: [], + })); + + rawResults = Object.entries(items).map(([key, value]) => ({ + item: { _type: key as keyof typeof items, ...placeholders }, + score: value.score, + refIndex: 0, + matches: [], + })); }); test("should group hits by type", () => { const expected = { komponent_artikkel: [ - { item: { _type: "komponent_artikkel" }, score: 0.05, matches: [] }, + { + item: { _type: "komponent_artikkel", ...placeholders }, + score: 0.05, + matches: [], + }, ], aksel_artikkel: [ - { item: { _type: "aksel_artikkel" }, score: 0.1, matches: [] }, + { + item: { _type: "aksel_artikkel", ...placeholders }, + score: 0.1, + matches: [], + }, ], ds_artikkel: [ - { item: { _type: "ds_artikkel" }, score: 0.15, matches: [] }, + { + item: { _type: "ds_artikkel", ...placeholders }, + score: 0.15, + matches: [], + }, ], aksel_blogg: [ - { item: { _type: "aksel_blogg" }, score: 0.2, matches: [] }, + { + item: { _type: "aksel_blogg", ...placeholders }, + score: 0.2, + matches: [], + }, ], aksel_prinsipp: [ - { item: { _type: "aksel_prinsipp" }, score: 0.25, matches: [] }, + { + item: { _type: "aksel_prinsipp", ...placeholders }, + score: 0.25, + matches: [], + }, ], aksel_standalone: [ - { item: { _type: "aksel_standalone" }, score: 0.3, matches: [] }, + { + item: { _type: "aksel_standalone", ...placeholders }, + score: 0.3, + matches: [], + }, ], }; const actual: SearchResultsT = createSearchResult(result, rawResults); @@ -76,7 +87,11 @@ describe("createSearchResult", () => { test("should return top 3 results with score < 0.1", () => { const expected = [ - { item: { _type: "komponent_artikkel" }, score: 0.05, matches: [] }, + { + item: { _type: "komponent_artikkel", ...placeholders }, + score: 0.05, + matches: [], + }, ]; const actual: SearchResultsT = createSearchResult(result, rawResults); expect(actual.topResults).toEqual(expected); diff --git a/aksel.nav.no/website/components/website-modules/search/providers/SearchNavigationProvider.tsx b/aksel.nav.no/website/components/website-modules/search/providers/SearchNavigationProvider.tsx index a6270df116..200cde027e 100644 --- a/aksel.nav.no/website/components/website-modules/search/providers/SearchNavigationProvider.tsx +++ b/aksel.nav.no/website/components/website-modules/search/providers/SearchNavigationProvider.tsx @@ -28,7 +28,7 @@ export const SearchNavigationProvider = ({ /* Add a small delay to get a precieved smoother navigation */ useEffect(() => { - let timeout: NodeJS.Timeout; + let timeout: ReturnType; const handler = () => { timeout && clearTimeout(timeout); diff --git a/biome.json b/biome.json index 7ce4a1d0c7..7d5c848ef0 100644 --- a/biome.json +++ b/biome.json @@ -41,7 +41,6 @@ "noShadowRestrictedNames": "off", "noArrayIndexKey": "off", "noAssignInExpressions": "off", - "noImplicitAnyLet": "off", "noDoubleEquals": "off", "noMisleadingCharacterClass": "off" },