Address some more low-hanging fruit for ts-strict-ignore (#6992)

* Address some more low-hanging fruit for ts-strict-ignore

* Add release notes

* Fix small issues

* Rabbit
This commit is contained in:
Julian Dominguez-Schatz
2026-02-16 10:30:27 -05:00
committed by GitHub
parent c031d9aa4f
commit e8f6ceeb98
15 changed files with 45 additions and 40 deletions

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import React, { useEffect, useState } from 'react';
import { DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
@@ -63,7 +62,7 @@ function AppInner() {
}, []);
useEffect(() => {
const maybeUpdate = async <T,>(cb?: () => T): Promise<T> => {
const maybeUpdate = async <T,>(cb?: () => T): Promise<T | void> => {
if (global.Actual.isUpdateReadyForDownload()) {
dispatch(
setAppState({

View File

@@ -96,7 +96,7 @@ export function BudgetTable(props: BudgetTableProps) {
const _onReorderCategory = (
id: string,
dropPos: DropPosition,
dropPos: DropPosition | null,
targetId: string,
) => {
const isGroup = !!categoryGroups.find(g => g.id === targetId);
@@ -137,7 +137,7 @@ export function BudgetTable(props: BudgetTableProps) {
const _onReorderGroup = (
id: string,
dropPos: DropPosition,
dropPos: DropPosition | null,
targetId: string,
) => {
const [expenseGroups] = separateGroups(categoryGroups); // exclude Income group from sortable groups to fix off-by-one error

View File

@@ -127,7 +127,7 @@ export function makeAmountFullStyle(
export function findSortDown<T extends { id: string }>(
arr: T[],
pos: DropPosition,
pos: DropPosition | null,
targetId: string,
) {
if (pos === 'top') {
@@ -151,7 +151,7 @@ export function findSortDown<T extends { id: string }>(
export function findSortUp<T extends { id: string }>(
arr: T[],
pos: DropPosition,
pos: DropPosition | null,
targetId: string,
) {
if (pos === 'bottom') {

View File

@@ -57,16 +57,16 @@ export function Accounts() {
async function onReorder(
id: string,
dropPos: 'top' | 'bottom',
targetId: unknown,
dropPos: 'top' | 'bottom' | null,
targetId: string,
) {
let targetIdToMove = targetId;
let targetIdToMove: string | null = targetId;
if (dropPos === 'bottom') {
const idx = accounts.findIndex(a => a.id === targetId) + 1;
targetIdToMove = idx < accounts.length ? accounts[idx].id : null;
}
moveAccount.mutate({ id, targetId: targetIdToMove as string });
moveAccount.mutate({ id, targetId: targetIdToMove });
}
const onToggleClosedAccounts = () => {

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import React, {
createContext,
useContext,
@@ -7,7 +6,6 @@ import React, {
useRef,
useState,
} from 'react';
import type { Context } from 'react';
import { useDrag, useDrop } from 'react-dnd';
import { theme } from '@actual-app/components/theme';
@@ -75,7 +73,7 @@ export function useDraggable<T>({
export type OnDropCallback = (
id: string,
dropPos: DropPosition,
dropPos: DropPosition | null,
targetId: string,
) => Promise<void> | void;
@@ -94,7 +92,7 @@ export function useDroppable<T extends { id: string }>({
onDrop,
onLongHover,
}: UseDroppableArgs) {
const ref = useRef(null);
const ref = useRef<HTMLDivElement | null>(null);
const onLongHoverRef = useRef(onLongHover);
const [dropPos, setDropPos] = useState<DropPosition | null>(null);
@@ -108,10 +106,12 @@ export function useDroppable<T extends { id: string }>({
onDrop(item.id, dropPos, id);
},
hover(_, monitor) {
if (!ref.current) return;
const hoverBoundingRect = ref.current.getBoundingClientRect();
const hoverMiddleY =
(hoverBoundingRect.bottom - hoverBoundingRect.top) / 2;
const clientOffset = monitor.getClientOffset();
if (!clientOffset) return;
const hoverClientY = clientOffset.y - hoverBoundingRect.top;
const pos: DropPosition = hoverClientY < hoverMiddleY ? 'top' : 'bottom';
@@ -147,8 +147,7 @@ export function useDroppable<T extends { id: string }>({
}
type ItemPosition = 'first' | 'last' | null;
export const DropHighlightPosContext: Context<ItemPosition> =
createContext(null);
export const DropHighlightPosContext = createContext<ItemPosition>(null);
type DropHighlightProps = {
pos: DropPosition;

View File

@@ -40,13 +40,13 @@ export function useAccountPreviewTransactions({
const payeesById = useMemo(() => groupById(payees), [payees]);
const getPayeeByTransferAccount = useCallback(
(transferAccountId?: AccountEntity['id']) =>
(transferAccountId?: AccountEntity['id'] | null) =>
payees.find(p => p.transfer_acct === transferAccountId) || null,
[payees],
);
const getTransferAccountByPayee = useCallback(
(payeeId?: PayeeEntity['id']) => {
(payeeId?: PayeeEntity['id'] | null) => {
if (!payeeId) {
return null;
}
@@ -145,10 +145,10 @@ type InverseBasedOnAccountProps = {
startingBalance: IntegerAmount;
runningBalances: Map<TransactionEntity['id'], IntegerAmount>;
getPayeeByTransferAccount: (
transferAccountId?: AccountEntity['id'],
transferAccountId?: AccountEntity['id'] | null,
) => PayeeEntity | null;
getTransferAccountByPayee: (
payeeId?: PayeeEntity['id'],
payeeId?: PayeeEntity['id'] | null,
) => AccountEntity | null;
};

View File

@@ -63,7 +63,7 @@ const resolveLanguage = (language: string) => {
return undefined;
};
export const setI18NextLanguage = (language: string) => {
export const setI18NextLanguage = (language: string | null) => {
const defaultLanguages = Array.isArray(navigator.languages)
? navigator.languages
: [navigator.language || 'en'];

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import 'fake-indexeddb/auto';
import { IDBFactory } from 'fake-indexeddb';

View File

@@ -1,7 +1,6 @@
// @ts-strict-ignore
import * as db from '../db';
export async function createPayee(description) {
export async function createPayee(description: string) {
// Check to make sure no payee already exists with exactly the same
// name
const row = await db.first<Pick<db.DbPayee, 'id'>>(

View File

@@ -224,7 +224,7 @@ handlers['api/download-budget'] = async function ({ syncId, password }) {
await handlers['load-budget']({ id: localBudget.id });
const result = await handlers['sync-budget']();
if (result.error) {
throw new Error(getSyncError(result.error, localBudget.id));
throw new Error(getSyncError(result.error.reason, localBudget.id));
}
return;
}
@@ -253,7 +253,7 @@ handlers['api/sync'] = async function () {
const { id } = prefs.getPrefs();
const result = await handlers['sync-budget']();
if (result.error) {
throw new Error(getSyncError(result.error, id));
throw new Error(getSyncError(result.error.reason, id));
}
};

View File

@@ -1,12 +1,11 @@
// @ts-strict-ignore
import { t } from 'i18next';
export function getUploadError({
reason,
meta,
}: {
type ErrorWithMeta = {
reason: string;
meta?: unknown;
}) {
};
export function getUploadError({ reason, meta }: ErrorWithMeta) {
switch (reason) {
case 'unauthorized':
return t('You are not logged in.');
@@ -89,11 +88,11 @@ export function getDownloadError({
}
}
export function getCreateKeyError(error) {
export function getCreateKeyError(error: ErrorWithMeta) {
return getUploadError(error);
}
export function getTestKeyError({ reason }) {
export function getTestKeyError({ reason }: ErrorWithMeta) {
switch (reason) {
case 'network':
return t(
@@ -112,7 +111,7 @@ export function getTestKeyError({ reason }) {
}
}
export function getSyncError(error, id) {
export function getSyncError(error: string, id: string) {
if (error === 'out-of-sync-migrations' || error === 'out-of-sync-data') {
return t('This budget cannot be loaded with this version of the app.');
} else if (error === 'budget-not-found') {

View File

@@ -15,7 +15,7 @@ export type ImportTransactionEntity = {
/** In a create/import request, this overrides payee_name.
* Should be an existing payee ID */
payee?: string;
payee?: string | null;
/** If given, a payee will be created with this name.
* If this matches an already existing payee, that payee will be used.

View File

@@ -13,7 +13,7 @@ export type TransactionEntity = {
account: AccountEntity['id'];
category?: CategoryEntity['id'];
amount: IntegerAmount;
payee?: PayeeEntity['id'];
payee?: PayeeEntity['id'] | null;
notes?: string;
date: string;
imported_id?: string;

View File

@@ -1,5 +1,9 @@
// @ts-strict-ignore
export {};
import type EventEmitter from 'events';
export type IpcClient = {
on: EventEmitter['on'];
emit: (name: string, data: unknown) => void;
};
type FileDialogOptions = {
properties?: Array<'openFile' | 'openDirectory'>;
@@ -28,7 +32,7 @@ type Actual = {
newDirectory: string,
) => Promise<void>;
applyAppUpdate: () => Promise<void>;
ipcConnect: (callback: (client) => void) => void;
ipcConnect: (callback: (client: IpcClient) => void) => void;
getServerSocket: () => Promise<Worker | null>;
setTheme: (theme: string) => void;
logToTerminal: (...args: unknown[]) => void;

View File

@@ -0,0 +1,6 @@
---
category: Maintenance
authors: [jfdoming]
---
Address some more low-hanging fruit for ts-strict-ignore