diff --git a/packages/loot-core/src/server/budget/types/handlers.d.ts b/packages/loot-core/src/server/budget/types/handlers.d.ts index bb3f696408086ff397939cb958e97865f8992f65..66c2f72c731da700c210696e16b8ccf5f66ff0f5 100644 --- a/packages/loot-core/src/server/budget/types/handlers.d.ts +++ b/packages/loot-core/src/server/budget/types/handlers.d.ts @@ -5,13 +5,13 @@ export interface BudgetHandlers { category: string /* category id */; month: string; amount: number; - }) => Promise<unknown>; + }) => Promise<void>; - 'budget/copy-previous-month': (...args: unknown[]) => Promise<unknown>; + 'budget/copy-previous-month': (arg: { month: string }) => Promise<void>; - 'budget/set-zero': (...args: unknown[]) => Promise<unknown>; + 'budget/set-zero': (arg: { month: string }) => Promise<void>; - 'budget/set-3month-avg': (...args: unknown[]) => Promise<unknown>; + 'budget/set-3month-avg': (arg: { month: string }) => Promise<void>; 'budget/check-templates': () => Promise<Notification>; @@ -27,17 +27,37 @@ export interface BudgetHandlers { month: string; }) => Promise<Notification>; - 'budget/hold-for-next-month': (...args: unknown[]) => Promise<unknown>; + 'budget/hold-for-next-month': (arg: { + month: string; + amount: number; + }) => Promise<boolean>; - 'budget/reset-hold': (...args: unknown[]) => Promise<unknown>; + 'budget/reset-hold': (arg: { month: string }) => Promise<void>; - 'budget/cover-overspending': (...args: unknown[]) => Promise<unknown>; + 'budget/cover-overspending': (arg: { + month: string; + to: string; + from: string; + }) => Promise<void>; - 'budget/transfer-available': (...args: unknown[]) => Promise<unknown>; + 'budget/transfer-available': (arg: { + month: string; + amount: number; + category: string; + }) => Promise<void>; - 'budget/transfer-category': (...args: unknown[]) => Promise<unknown>; + 'budget/transfer-category': (arg: { + month: string; + amount: number; + to: string; + from: string; + }) => Promise<void>; - 'budget/set-carryover': (...args: unknown[]) => Promise<unknown>; + 'budget/set-carryover': (arg: { + startMonth: string; + category: string; + flag: boolean; + }) => Promise<void>; 'budget/apply-single-template': (arg: { month: string; @@ -48,10 +68,10 @@ export interface BudgetHandlers { month: string; N: number; category: string; //category id - }) => Promise<unknown>; + }) => Promise<void>; 'budget/copy-single-month': (arg: { month: string; category: string; //category id - }) => Promise<unknown>; + }) => Promise<void>; } diff --git a/packages/loot-core/src/server/mutators.ts b/packages/loot-core/src/server/mutators.ts index 9d85c08615784e07c35bf41cacc991efddee76c1..3988e5c58f813f806ea8f2bf7f874693f09bfef6 100644 --- a/packages/loot-core/src/server/mutators.ts +++ b/packages/loot-core/src/server/mutators.ts @@ -1,5 +1,6 @@ import { captureException, captureBreadcrumb } from '../platform/exceptions'; import { sequential } from '../shared/async'; +import { type HandlerFunctions } from '../types/handlers'; const runningMethods = new Set(); @@ -9,9 +10,7 @@ let globalMutationsEnabled = false; let _latestHandlerNames = []; -export function mutator<T extends (...args: unknown[]) => unknown>( - handler: T, -): T { +export function mutator<T extends HandlerFunctions>(handler: T): T { mutatingMethods.set(handler, true); return handler; } diff --git a/packages/loot-core/src/server/undo.ts b/packages/loot-core/src/server/undo.ts index faf5fa9278dd9244b21accc59f1d97d1c07005fb..ac12e9c388c59e3423572bbbb48491f1c645e61d 100644 --- a/packages/loot-core/src/server/undo.ts +++ b/packages/loot-core/src/server/undo.ts @@ -2,6 +2,7 @@ import { Timestamp } from '@actual-app/crdt'; import * as connection from '../platform/server/connection'; import { getIn } from '../shared/util'; +import { type HandlerFunctions } from '../types/handlers'; import { withMutatorContext, getMutatorContext } from './mutators'; import { Message, sendMessages } from './sync'; @@ -89,18 +90,10 @@ export function withUndo<T>( ); } -// for some reason `void` is not inferred properly without this overload -export function undoable<Args extends unknown[]>( - func: (...args: Args) => Promise<void>, -): (...args: Args) => Promise<void>; -export function undoable< - Args extends unknown[], - Return extends Promise<unknown>, ->(func: (...args: Args) => Return): (...args: Args) => Return; -export function undoable(func: (...args: unknown[]) => Promise<unknown>) { - return (...args: unknown[]) => { - return withUndo(() => { - return func(...args); +export function undoable<T extends HandlerFunctions>(func: T) { + return (...args: Parameters<T>) => { + return withUndo<Awaited<ReturnType<T>>>(() => { + return func.apply(null, args); }); }; } diff --git a/packages/loot-core/src/shared/async.ts b/packages/loot-core/src/shared/async.ts index 718204f3663c635189641fc4a31e831e94057041..0e6a0c92200faf66d5063c5bd5ce70ce73b38112 100644 --- a/packages/loot-core/src/shared/async.ts +++ b/packages/loot-core/src/shared/async.ts @@ -1,4 +1,6 @@ -export function sequential<T extends (...args: unknown[]) => unknown>( +import { type HandlerFunctions } from '../types/handlers'; + +export function sequential<T extends HandlerFunctions>( fn: T, ): (...args: Parameters<T>) => Promise<Awaited<ReturnType<T>>> { const sequenceState = { @@ -16,7 +18,7 @@ export function sequential<T extends (...args: unknown[]) => unknown>( } function run(args, resolve, reject) { - sequenceState.running = fn(...args); + sequenceState.running = fn.apply(null, args); sequenceState.running.then( val => { @@ -43,13 +45,13 @@ export function sequential<T extends (...args: unknown[]) => unknown>( }; } -export function once<T extends (...args: unknown[]) => Promise<unknown>>( +export function once<T extends HandlerFunctions>( fn: T, ): (...args: Parameters<T>) => Promise<Awaited<ReturnType<T>>> { let promise = null; - const onceFn = (...args: Parameters<T>): Promise<Awaited<ReturnType<T>>> => { + return (...args) => { if (!promise) { - promise = fn(...args).finally(() => { + promise = fn.apply(null, args).finally(() => { promise = null; }); return promise; @@ -57,6 +59,4 @@ export function once<T extends (...args: unknown[]) => Promise<unknown>>( return promise; }; - - return onceFn; } diff --git a/packages/loot-core/src/types/api-handlers.d.ts b/packages/loot-core/src/types/api-handlers.d.ts index 30e7b5b66bca95b839b20042e5ad7e4b37f05a85..71bc15306665e3b3579144325ec54458a5f9b976 100644 --- a/packages/loot-core/src/types/api-handlers.d.ts +++ b/packages/loot-core/src/types/api-handlers.d.ts @@ -1,3 +1,5 @@ +import { type ServerHandlers } from './server-handlers'; + export interface ApiHandlers { 'api/batch-budget-start': () => Promise<unknown>; @@ -5,7 +7,7 @@ export interface ApiHandlers { 'api/load-budget': ( ...args: Parameters<ServerHandlers['load-budget']> - ) => Promise<unknown>; + ) => Promise<void>; 'api/download-budget': (arg: { syncId; password }) => Promise<unknown>; diff --git a/packages/loot-core/src/types/handlers.d.ts b/packages/loot-core/src/types/handlers.d.ts index 2537c0279622286650a0a5bbec2925c3d7a8f0c0..7d131d44554d71001019c0127f537e13ae8a5634 100644 --- a/packages/loot-core/src/types/handlers.d.ts +++ b/packages/loot-core/src/types/handlers.d.ts @@ -17,3 +17,5 @@ export interface Handlers RulesHandlers, SchedulesHandlers, ToolsHandlers {} + +export type HandlerFunctions = Handlers[keyof Handlers]; diff --git a/packages/loot-core/src/types/server-handlers.d.ts b/packages/loot-core/src/types/server-handlers.d.ts index 1e85f00458db4c9d82472285cc284b3f9b67bcb2..cb1f0c8cfe53c06778f72790cf061aa71a154f67 100644 --- a/packages/loot-core/src/types/server-handlers.d.ts +++ b/packages/loot-core/src/types/server-handlers.d.ts @@ -326,7 +326,7 @@ export interface ServerHandlers { error?: { message: string; reason: string; meta: unknown }; }>; - 'load-budget': (arg: { id }) => Promise<{ error }>; + 'load-budget': (arg: { id: string }) => Promise<{ error }>; 'create-demo-budget': () => Promise<unknown>; diff --git a/tsconfig.json b/tsconfig.json index 1a4dce7bf8f63fad28348250843586da9f2ea9c3..844bcaf11c498cf93efafb1e1f6c1da9a8f1654d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -15,6 +15,8 @@ "downlevelIteration": true, // TODO: enable once every file is ts // "strict": true, + // TODO: enable once the violations are fixed + // "strictFunctionTypes": true, "noFallthroughCasesInSwitch": true, "skipLibCheck": true, "jsx": "preserve", diff --git a/upcoming-release-notes/2065.md b/upcoming-release-notes/2065.md new file mode 100644 index 0000000000000000000000000000000000000000..873d58604ec39bd94db0e4b2139d666625cc6131 --- /dev/null +++ b/upcoming-release-notes/2065.md @@ -0,0 +1,6 @@ +--- +category: Maintenance +authors: [MatissJanis] +--- + +Fixing TypeScript issues when enabling `strictFunctionTypes`.