From f865a22a0c5933f88a9790289de42e43809ff8db Mon Sep 17 00:00:00 2001 From: Micah Date: Sun, 3 May 2026 11:22:29 -0400 Subject: [PATCH 1/3] chore: upgrade to React 17, TypeScript 4.9, and Node 16 baseline - Add .nvmrc pinned to Node 16 - Upgrade react and react-dom from ^16.13.1 to ^17.0.2 - Upgrade typescript from ~3.9.7 to ~4.9.5 - Upgrade @types/node from ^11.9.3 to ^16.0.0 - Upgrade @types/react from ^16.9.0 to ^17.0.0 - Upgrade @types/react-dom from ^16.9.0 to ^17.0.0 - Add resolutions for @types/react and @types/react-dom to prevent duplicate versions causing JSX component type conflicts Fix type errors introduced by stricter TypeScript 4.9 checks: - Cast Link as any in IconButton component prop (Collection.tsx, CollectionList.tsx) to work around MUI 4 typing limitations - Replace endDate getter override in TaskType with Object.defineProperty in constructor (pim-types.ts) since TS 4.9 disallows overriding a class property with an accessor - Wrap ExternalLink with React.forwardRef so MUI ButtonBase can attach refs when used as a component prop (ExternalLink.tsx) --- .nvmrc | 1 + package.json | 18 ++++--- src/Collections/Collection.tsx | 4 +- src/Collections/CollectionList.tsx | 2 +- src/pim-types.ts | 12 +++-- src/widgets/ExternalLink.tsx | 6 +-- yarn.lock | 75 ++++++++++++++++-------------- 7 files changed, 66 insertions(+), 52 deletions(-) create mode 100644 .nvmrc diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 00000000..b6a7d89c --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +16 diff --git a/package.json b/package.json index dbf7786e..d5321c0c 100644 --- a/package.json +++ b/package.json @@ -16,9 +16,9 @@ "localforage": "^1.9.0", "memoizee": "^0.4.14", "moment": "^2.27.0", - "react": "^16.13.1", + "react": "^17.0.2", "react-big-calendar": "^0.26.0", - "react-dom": "^16.13.1", + "react-dom": "^17.0.2", "react-dropzone": "^10.0.4", "react-redux": "^7.2.1", "react-router": "^5.2.0", @@ -48,10 +48,10 @@ "@types/color": "^3.0.1", "@types/jest": "^24.0.4", "@types/memoizee": "^0.4.4", - "@types/node": "^11.9.3", - "@types/react": "^16.9.0", + "@types/node": "^16.0.0", + "@types/react": "^17.0.0", "@types/react-big-calendar": "^0.22.3", - "@types/react-dom": "^16.9.0", + "@types/react-dom": "^17.0.0", "@types/react-redux": "^7.1.9", "@types/react-router": "^5.1.8", "@types/react-router-dom": "^5.1.5", @@ -60,12 +60,16 @@ "@types/redux-logger": "^3.0.8", "@types/urijs": "^1.15.38", "@types/uuid": "^3.4.3", - "typescript": "~3.9.7" + "typescript": "~4.9.5" }, "browserslist": [ ">0.2%", "not dead", "not ie <= 11", "not op_mini all" - ] + ], + "resolutions": { + "@types/react": "^17.0.0", + "@types/react-dom": "^17.0.0" + } } diff --git a/src/Collections/Collection.tsx b/src/Collections/Collection.tsx index 1782e253..480a8364 100644 --- a/src/Collections/Collection.tsx +++ b/src/Collections/Collection.tsx @@ -52,14 +52,14 @@ class Collection extends React.Component { {isAdmin && <> diff --git a/src/Collections/CollectionList.tsx b/src/Collections/CollectionList.tsx index 28c54271..043b0b94 100644 --- a/src/Collections/CollectionList.tsx +++ b/src/Collections/CollectionList.tsx @@ -58,7 +58,7 @@ export default function CollectionList(props: PropsType) { diff --git a/src/pim-types.ts b/src/pim-types.ts index fbc16876..d73eb1f5 100644 --- a/src/pim-types.ts +++ b/src/pim-types.ts @@ -185,6 +185,13 @@ export class TaskType extends EventType { constructor(comp?: ICAL.Component | null) { super(comp ? comp : new ICAL.Component("vtodo")); + // Override endDate — not applicable for tasks + Object.defineProperty(this, "endDate", { + get() { + return undefined as any; + }, + configurable: true, + }); } get finished() { @@ -264,11 +271,6 @@ export class TaskType extends EventType { return this.component.getFirstPropertyValue("related-to"); } - get endDate() { - // XXX: A hack to override this as it shouldn't be used - return undefined as any; - } - get allDay() { return !!((this.startDate?.isDate) || (this.dueDate?.isDate)); } diff --git a/src/widgets/ExternalLink.tsx b/src/widgets/ExternalLink.tsx index 4f1e8182..56089424 100644 --- a/src/widgets/ExternalLink.tsx +++ b/src/widgets/ExternalLink.tsx @@ -3,10 +3,10 @@ import * as React from "react"; -export const ExternalLink = React.memo(({ children, ...props }: any) => ( - +export const ExternalLink = React.memo(React.forwardRef(({ children, ...props }, ref) => ( + {children} -)); +))); export default ExternalLink; diff --git a/yarn.lock b/yarn.lock index ab08955e..0421124d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1827,10 +1827,10 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.27.tgz#a151873af5a5e851b51b3b065c9e63390a9e0eb1" integrity sha512-kVrqXhbclHNHGu9ztnAwSncIgJv/FaxmzXJvGXNdcCpV1b8u1/Mi6z6m0vwy0LzKeXFTPLH0NzwmoJ3fNCIq0g== -"@types/node@^11.9.3": - version "11.15.20" - resolved "https://registry.yarnpkg.com/@types/node/-/node-11.15.20.tgz#dacd63b282c1a0d40fa0ad216b7ca128afded614" - integrity sha512-DY2QwdrBqNlsxdMehwzUtSsWHgYYPLVCAuXvOcu3wkzYmchbRunQ7OEZFOrmFoBLfA1ysz2Ypr6vtNP9WQkUaQ== +"@types/node@^16.0.0": + version "16.18.126" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.126.tgz#27875faa2926c0f475b39a8bb1e546c0176f8d4b" + integrity sha512-OTcgaiwfGFBKacvfwuHzzn1KLxH/er8mluiy8/uM3sGXHaRe73RrSIj01jow9t4kJEW633Ov+cOexXeiApTyAw== "@types/parse-json@^4.0.0": version "4.0.0" @@ -1855,12 +1855,10 @@ "@types/prop-types" "*" "@types/react" "*" -"@types/react-dom@*", "@types/react-dom@^16.9.0": - version "16.9.8" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.9.8.tgz#fe4c1e11dfc67155733dfa6aa65108b4971cb423" - integrity sha512-ykkPQ+5nFknnlU6lDd947WbQ6TE3NNzbQAkInC2EKY1qeYdTKp7onFusmYZb+ityzx2YviqT6BXSu+LyWWJwcA== - dependencies: - "@types/react" "*" +"@types/react-dom@*", "@types/react-dom@^17.0.0": + version "17.0.26" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.26.tgz#fa7891ba70fd39ddbaa7e85b6ff9175bb546bc1b" + integrity sha512-Z+2VcYXJwOqQ79HreLU/1fyQ88eXSSFh6I3JdrEHQIfYSI0kCQpTGvOrbE6jFGGYXKsHuwY9tBa/w5Uo6KzrEg== "@types/react-redux@^7.1.9": version "7.1.9" @@ -1904,13 +1902,14 @@ "@types/prop-types" "*" "@types/react" "*" -"@types/react@*", "@types/react@^16.9.0", "@types/react@^16.9.11": - version "16.9.44" - resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.44.tgz#da84b179c031aef67dc92c33bd3401f1da2fa3bc" - integrity sha512-BtLoJrXdW8DVZauKP+bY4Kmiq7ubcJq+H/aCpRfvPF7RAT3RwR73Sg8szdc2YasbAlWBDrQ6Q+AFM0KwtQY+WQ== +"@types/react@*", "@types/react@^16.9.11", "@types/react@^17.0.0": + version "17.0.91" + resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.91.tgz#0a972a41c430f56d2feb7c15368bc51642495e0b" + integrity sha512-xauZca6qMeCU3Moy0KxCM9jtf1vyk6qRYK39Ryf3afUqwgNUjRIGoDdS9BcGWgAMGSg1hvP4XcmlYrM66PtqeA== dependencies: "@types/prop-types" "*" - csstype "^3.0.2" + "@types/scheduler" "^0.16" + csstype "^3.2.2" "@types/redux-actions@^2.6.1": version "2.6.1" @@ -1924,6 +1923,11 @@ dependencies: redux "^4.0.0" +"@types/scheduler@^0.16": + version "0.16.8" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.8.tgz#ce5ace04cfeabe7ef87c0091e50752e36707deff" + integrity sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A== + "@types/stack-utils@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" @@ -3955,6 +3959,11 @@ csstype@^3.0.2: resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.2.tgz#ee5ff8f208c8cd613b389f7b222c9801ca62b3f7" integrity sha512-ofovWglpqoqbfLNOTBNZLSbMuGrblAf1efvvArGKOZMBrIoJeu5UsAipQolkijtyQx5MtAzT/J9IHj/CEY1mJw== +csstype@^3.2.2: + version "3.2.3" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.2.3.tgz#ec48c0f3e993e50648c86da559e2610995cf989a" + integrity sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ== + cyclist@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" @@ -9469,15 +9478,14 @@ react-dev-utils@^10.2.1: strip-ansi "6.0.0" text-table "0.2.0" -react-dom@^16.13.1: - version "16.13.1" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.13.1.tgz#c1bd37331a0486c078ee54c4740720993b2e0e7f" - integrity sha512-81PIMmVLnCNLO/fFOQxdQkvEq/+Hfpv24XNJfpyZhTRfO0QcmQIF/PgCa1zCOj2w1hrn12MFLyaJ/G0+Mxtfag== +react-dom@^17.0.2: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23" + integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" - prop-types "^15.6.2" - scheduler "^0.19.1" + scheduler "^0.20.2" react-dropzone@^10.0.4: version "10.2.2" @@ -9638,14 +9646,13 @@ react-virtualized@^9.21.2: prop-types "^15.6.0" react-lifecycles-compat "^3.0.4" -react@^16.13.1: - version "16.13.1" - resolved "https://registry.yarnpkg.com/react/-/react-16.13.1.tgz#2e818822f1a9743122c063d6410d85c1e3afe48e" - integrity sha512-YMZQQq32xHLX0bz5Mnibv1/LHb3Sqzngu7xstSM+vrkE5Kzr9xE0yMByK5kMoTK30YVJE61WfbxIFFvfeDKT1w== +react@^17.0.2: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037" + integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" - prop-types "^15.6.2" read-pkg-up@^2.0.0: version "2.0.0" @@ -10185,10 +10192,10 @@ saxes@^3.1.9: dependencies: xmlchars "^2.1.1" -scheduler@^0.19.1: - version "0.19.1" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.19.1.tgz#4f3e2ed2c1a7d65681f4c854fa8c5a1ccb40f196" - integrity sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA== +scheduler@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91" + integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" @@ -11268,10 +11275,10 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= -typescript@~3.9.7: - version "3.9.7" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.7.tgz#98d600a5ebdc38f40cb277522f12dc800e9e25fa" - integrity sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw== +typescript@~4.9.5: + version "4.9.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" + integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== uncontrollable@^7.0.0: version "7.1.1" From f8519a45c472b52a06aba88bdc86cf5c35f5df80 Mon Sep 17 00:00:00 2001 From: Micah Date: Sun, 3 May 2026 15:14:08 -0400 Subject: [PATCH 2/3] fix: resolve TypeScript strict type-checking errors across codebase - tsconfig.json: Remove deprecated suppressImplicitAnyIndexErrors option, add ignoreDeprecations: '6.0' for other legacy options - Add explicit Record type annotations to object literals used with dynamic string keys: - CollectionEdit: colTypes - CollectionImport, CollectionList: collectionMap - ContactEdit, GroupEdit: collectionGroups, originalGroups, groups - Contacts/Toolbar, Tasks/Toolbar: transitionStyles (Record) - Debug: wantedEntries (Record) - persist-state-history: stateCache - routes: RouteResolver.routes and constructor param - Cast dynamic state property access to (prevState as any)[name] in ContactEdit and GroupEdit (addValueType, removeValueType, handleValueTypeChange methods) - Cast zones.zones and zones.aliases to Record in pim-types.ts timezoneLoadFromName for bracket notation access - Cast actions to Record in store/reducers.ts for dynamic property access in fetchActions loop - Cast updatedOptions to Record in RRule.tsx for dynamic key iteration and deletion; cast bysetpos and bymonthday to number[] for array element access - Add Record constraint to insertSorted generic in helpers.tsx; cast self.state[part] for dynamic property access in handleInputChange - Replace theme.palette.primary[500] with theme.palette.primary.main in SearchableAddressBook and TaskList (Material-UI v4 best practice) --- src/Collections/CollectionEdit.tsx | 2 +- src/Collections/CollectionImport.tsx | 2 +- src/Collections/CollectionList.tsx | 2 +- src/Contacts/ContactEdit.tsx | 12 ++++++------ src/Contacts/GroupEdit.tsx | 8 ++++---- src/Contacts/SearchableAddressBook.tsx | 2 +- src/Contacts/Toolbar.tsx | 2 +- src/Debug.tsx | 2 +- src/Tasks/TaskList.tsx | 2 +- src/Tasks/Toolbar.tsx | 2 +- src/helpers.tsx | 4 ++-- src/persist-state-history.tsx | 2 +- src/pim-types.ts | 6 +++--- src/routes.ts | 4 ++-- src/store/reducers.ts | 2 +- src/widgets/RRule.tsx | 8 ++++---- tsconfig.json | 2 +- 17 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/Collections/CollectionEdit.tsx b/src/Collections/CollectionEdit.tsx index 8983b1e0..abe15d5a 100644 --- a/src/Collections/CollectionEdit.tsx +++ b/src/Collections/CollectionEdit.tsx @@ -126,7 +126,7 @@ export default function CollectionEdit(props: PropsType) { }, }; - const colTypes = { + const colTypes: Record = { "etebase.vcard": "Address Book", "etebase.vevent": "Calendar", "etebase.vtodo": "Task List", diff --git a/src/Collections/CollectionImport.tsx b/src/Collections/CollectionImport.tsx index 683db69f..1f405291 100644 --- a/src/Collections/CollectionImport.tsx +++ b/src/Collections/CollectionImport.tsx @@ -23,7 +23,7 @@ interface PropsType { export default function CollectionImport(props: PropsType) { const [selectedCollection, setSelectedCollection] = React.useState(); - const collectionMap = { + const collectionMap: Record = { "etebase.vcard": [], "etebase.vevent": [], "etebase.vtodo": [], diff --git a/src/Collections/CollectionList.tsx b/src/Collections/CollectionList.tsx index 043b0b94..cf7829b7 100644 --- a/src/Collections/CollectionList.tsx +++ b/src/Collections/CollectionList.tsx @@ -27,7 +27,7 @@ interface PropsType { export default function CollectionList(props: PropsType) { const history = useHistory(); - const collectionMap = { + const collectionMap: Record = { "etebase.vcard": [], "etebase.vevent": [], "etebase.vtodo": [], diff --git a/src/Contacts/ContactEdit.tsx b/src/Contacts/ContactEdit.tsx index 3983bc85..50c89acb 100644 --- a/src/Contacts/ContactEdit.tsx +++ b/src/Contacts/ContactEdit.tsx @@ -147,9 +147,9 @@ class ContactEdit extends React.PureComponent { collectionUid: string; showDeleteDialog: boolean; - collectionGroups: {}; + collectionGroups: Record; newGroups: string[]; - originalGroups: {}; + originalGroups: Record; }; constructor(props: PropsType) { @@ -264,7 +264,7 @@ class ContactEdit extends React.PureComponent { public addValueType(name: string, _type?: string) { const type = _type ? _type : "home"; this.setState((prevState) => { - const newArray = prevState[name].slice(0); + const newArray = (prevState as any)[name].slice(0); newArray.push(new ValueType(type)); return { ...prevState, @@ -275,7 +275,7 @@ class ContactEdit extends React.PureComponent { public removeValueType(name: string, idx: number) { this.setState((prevState) => { - const newArray = prevState[name].slice(0); + const newArray = (prevState as any)[name].slice(0); newArray.splice(idx, 1); return { ...prevState, @@ -286,7 +286,7 @@ class ContactEdit extends React.PureComponent { public handleValueTypeChange(name: string, idx: number, value: ValueType) { this.setState((prevState) => { - const newArray = prevState[name].slice(0); + const newArray = (prevState as any)[name].slice(0); newArray[idx] = value; return { ...prevState, @@ -302,7 +302,7 @@ class ContactEdit extends React.PureComponent { } public getCollectionGroups(collectionUid: string) { - const groups = {}; + const groups: Record = {}; this.props.allGroups.forEach((group) => { if (collectionUid === group.collectionUid) { groups[group.fn] = group; diff --git a/src/Contacts/GroupEdit.tsx b/src/Contacts/GroupEdit.tsx index fec34e9b..954474cd 100644 --- a/src/Contacts/GroupEdit.tsx +++ b/src/Contacts/GroupEdit.tsx @@ -97,7 +97,7 @@ class GroupEdit extends React.PureComponent { public addValueType(name: string, _type?: string) { const type = _type ? _type : "home"; this.setState((prevState) => { - const newArray = prevState[name].slice(0); + const newArray = (prevState as any)[name].slice(0); newArray.push(new ValueType(type)); return { ...prevState, @@ -108,7 +108,7 @@ class GroupEdit extends React.PureComponent { public removeValueType(name: string, idx: number) { this.setState((prevState) => { - const newArray = prevState[name].slice(0); + const newArray = (prevState as any)[name].slice(0); newArray.splice(idx, 1); return { ...prevState, @@ -119,7 +119,7 @@ class GroupEdit extends React.PureComponent { public handleValueTypeChange(name: string, idx: number, value: ValueType) { this.setState((prevState) => { - const newArray = prevState[name].slice(0); + const newArray = (prevState as any)[name].slice(0); newArray[idx] = value; return { ...prevState, @@ -135,7 +135,7 @@ class GroupEdit extends React.PureComponent { } public getCollectionGroups(collectionUid: string) { - const groups = {}; + const groups: Record = {}; this.props.allGroups.forEach((group) => { if (collectionUid === group.collectionUid) { groups[group.fn] = null; diff --git a/src/Contacts/SearchableAddressBook.tsx b/src/Contacts/SearchableAddressBook.tsx index 9fb894bb..e4ca0abf 100644 --- a/src/Contacts/SearchableAddressBook.tsx +++ b/src/Contacts/SearchableAddressBook.tsx @@ -15,7 +15,7 @@ import AddressBook from "./AddressBook"; const useStyles = makeStyles((theme) => ({ topBar: { - backgroundColor: theme.palette.primary[500], + backgroundColor: theme.palette.primary.main, }, })); diff --git a/src/Contacts/Toolbar.tsx b/src/Contacts/Toolbar.tsx index dab0db45..0b131a5b 100644 --- a/src/Contacts/Toolbar.tsx +++ b/src/Contacts/Toolbar.tsx @@ -8,7 +8,7 @@ import InputAdornment from "@material-ui/core/InputAdornment"; const transitionTimeout = 300; -const transitionStyles = { +const transitionStyles: Record = { entering: { visibility: "visible", width: "100%", overflow: "hidden" }, entered: { visibility: "visible", width: "100%" }, exiting: { visibility: "visible", width: "0%", overflow: "hidden" }, diff --git a/src/Debug.tsx b/src/Debug.tsx index 6a3c0e82..6ae1b212 100644 --- a/src/Debug.tsx +++ b/src/Debug.tsx @@ -63,7 +63,7 @@ export default function Debug() { const col = colMgr.cacheLoad(cachedCollection); const itemMgr = colMgr.getItemManager(col); - const wantedEntries = {}; + const wantedEntries: Record = {}; const wantAll = (itemsUids.trim() === "all"); itemsUids.split("\n").forEach((ent) => wantedEntries[ent.trim()] = true); diff --git a/src/Tasks/TaskList.tsx b/src/Tasks/TaskList.tsx index b2fa1e3b..7af3e73a 100644 --- a/src/Tasks/TaskList.tsx +++ b/src/Tasks/TaskList.tsx @@ -94,7 +94,7 @@ function getSortFunction(sortOrder: string) { const useStyles = makeStyles((theme) => ({ topBar: { - backgroundColor: theme.palette.primary[500], + backgroundColor: theme.palette.primary.main, }, })); diff --git a/src/Tasks/Toolbar.tsx b/src/Tasks/Toolbar.tsx index 2fd877b1..3d8bc228 100644 --- a/src/Tasks/Toolbar.tsx +++ b/src/Tasks/Toolbar.tsx @@ -24,7 +24,7 @@ import { CachedCollection } from "../Pim/helpers"; const transitionTimeout = 300; -const transitionStyles = { +const transitionStyles: Record = { entering: { visibility: "visible", width: "100%", overflow: "hidden" }, entered: { visibility: "visible", width: "100%" }, exiting: { visibility: "visible", width: "0%", overflow: "hidden" }, diff --git a/src/helpers.tsx b/src/helpers.tsx index d77d7894..49ac6b65 100644 --- a/src/helpers.tsx +++ b/src/helpers.tsx @@ -29,7 +29,7 @@ export function handleInputChange(self: React.Component, part?: string) { } else { self.setState({ [part]: { - ...self.state[part], + ...(self.state as Record)[part], ...newState, }, }); @@ -37,7 +37,7 @@ export function handleInputChange(self: React.Component, part?: string) { }; } -export function insertSorted(array: T[] = [], newItem: T, key: string) { +export function insertSorted>(array: T[] = [], newItem: T, key: string) { if (array.length === 0) { return [newItem]; } diff --git a/src/persist-state-history.tsx b/src/persist-state-history.tsx index bc7ddbcd..3088fbd6 100644 --- a/src/persist-state-history.tsx +++ b/src/persist-state-history.tsx @@ -5,7 +5,7 @@ import * as React from "react"; import { withRouter } from "react-router"; // FIXME: Should probably tie this to the history object, or at least based on the depth of the history -const stateCache = {}; +const stateCache: Record = {}; type Constructor = new(...args: any[]) => T; diff --git a/src/pim-types.ts b/src/pim-types.ts index d73eb1f5..cee3e7bf 100644 --- a/src/pim-types.ts +++ b/src/pim-types.ts @@ -22,9 +22,9 @@ export function timezoneLoadFromName(timezone: string | null) { return null; } - let zone = zones.zones[timezone]; - if (!zone && zones.aliases[timezone]) { - zone = zones.zones[zones.aliases[timezone]]; + let zone = (zones.zones as Record)[timezone]; + if (!zone && (zones.aliases as Record)[timezone]) { + zone = (zones.zones as Record)[(zones.aliases as Record)[timezone].aliasTo]; } if (!zone) { diff --git a/src/routes.ts b/src/routes.ts index eab05973..4440d7ce 100644 --- a/src/routes.ts +++ b/src/routes.ts @@ -6,9 +6,9 @@ export interface RouteKeysType { } export class RouteResolver { - public routes: {}; + public routes: Record; - constructor(routes: {}) { + constructor(routes: Record) { this.routes = routes; } diff --git a/src/store/reducers.ts b/src/store/reducers.ts index 11b31741..3f5444f0 100644 --- a/src/store/reducers.ts +++ b/src/store/reducers.ts @@ -179,7 +179,7 @@ for (const func in actions) { func.startsWith("update") || func.startsWith("delete")) { - fetchActions.push(actions[func]); + fetchActions.push((actions as Record)[func]); } } diff --git a/src/widgets/RRule.tsx b/src/widgets/RRule.tsx index e7b8ddda..46e2d4bb 100644 --- a/src/widgets/RRule.tsx +++ b/src/widgets/RRule.tsx @@ -124,9 +124,9 @@ export default function RRule(props: PropsType) { } for (const key of Object.keys(updatedOptions)) { - const value = updatedOptions[key]; + const value = (updatedOptions as Record)[key]; if ((value === undefined) || (value?.length === 0)) { - delete updatedOptions[key]; + delete (updatedOptions as Record)[key]; continue; } } @@ -206,7 +206,7 @@ export default function RRule(props: PropsType) { } {options.bysetpos && -