refactor(types): typed send helpers replace 16 as any casts (#210)
- sendRoomMessage (composer's fire-and-forget sends: text, location, voice, files, GIFs) and sendRoomEvent (polls, poll responses/ends, forwards, reactions, edits) in utils/room.ts carry the one cast each needs (`keyof TimelineEvents` / `RoomMessageEventContent`, no `any`). - sendRoomMessage also swallows the rejected promise: a failed send already shows on the local echo (Failed to send + Retry, or the consent prompt), so it no longer surfaces as an unhandled error in the console. - getAccountData narrows to `keyof AccountDataEvents`; ForwardMessageDialog's guard now narrows `contentToSend` itself (same behaviour). - `as any` 39 → 23; eslint warnings 46 → 36, ratchet tightened to 36. Verified in Chromium on a local Synapse: a text message, a quick reaction and an edit all reach the server with the right content; a consent-blocked send no longer logs an unhandled MatrixError. 1219 unit tests pass. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
39589b40f3
commit
e39714a6e0
+38
-1
@@ -1,9 +1,11 @@
|
||||
import { IconName, IconSrc } from 'folds';
|
||||
|
||||
import {
|
||||
AccountDataEvents,
|
||||
EventTimeline,
|
||||
EventTimelineSet,
|
||||
EventType,
|
||||
IContent,
|
||||
IMentions,
|
||||
IPowerLevelsContent,
|
||||
IPushRule,
|
||||
@@ -17,8 +19,10 @@ import {
|
||||
RelationType,
|
||||
Room,
|
||||
RoomMember,
|
||||
TimelineEvents,
|
||||
} from 'matrix-js-sdk';
|
||||
import { CryptoBackend } from 'matrix-js-sdk/lib/common-crypto/CryptoBackend';
|
||||
import type { RoomMessageEventContent } from 'matrix-js-sdk/lib/@types/events';
|
||||
import { AccountDataEvent } from '../../types/matrix/accountData';
|
||||
import {
|
||||
IRoomCreateContent,
|
||||
@@ -62,10 +66,43 @@ export function sendStateEvent<T extends object>(
|
||||
return mx.sendStateEvent(roomId, eventType as any, content, stateKey);
|
||||
}
|
||||
|
||||
// Typed message send for the composer's fire-and-forget sends. The SDK's
|
||||
// `sendMessage` wants its `RoomMessageEventContent` union, which the composer's
|
||||
// extensible content (MSC3488 location, MSC3245 voice, `m.mentions`, encrypted
|
||||
// `file`) doesn't narrow to; the single cast lives here. A failed send already
|
||||
// shows on the local echo ("Failed to send" with Retry, or the consent prompt),
|
||||
// so the rejection is swallowed rather than surfacing as an unhandled error.
|
||||
export function sendRoomMessage(
|
||||
mx: MatrixClient,
|
||||
roomId: string,
|
||||
threadId: string | null,
|
||||
content: IContent,
|
||||
): void {
|
||||
mx.sendMessage(roomId, threadId, content as RoomMessageEventContent).catch(() => undefined);
|
||||
}
|
||||
|
||||
// Typed send for events whose type isn't one of the SDK's typed timeline events
|
||||
// (MSC3381 polls, forwarded arbitrary types, the fork's reaction enum) or whose
|
||||
// content is extensible. Keeps the one cast out of every call site.
|
||||
export function sendRoomEvent(
|
||||
mx: MatrixClient,
|
||||
roomId: string,
|
||||
threadId: string | null,
|
||||
eventType: string,
|
||||
content: IContent,
|
||||
): Promise<ISendEventResponse> {
|
||||
return mx.sendEvent(
|
||||
roomId,
|
||||
threadId,
|
||||
eventType as keyof TimelineEvents,
|
||||
content as TimelineEvents[keyof TimelineEvents],
|
||||
);
|
||||
}
|
||||
|
||||
export const getAccountData = (
|
||||
mx: MatrixClient,
|
||||
eventType: AccountDataEvent | string,
|
||||
): MatrixEvent | undefined => mx.getAccountData(eventType as any);
|
||||
): MatrixEvent | undefined => mx.getAccountData(eventType as keyof AccountDataEvents);
|
||||
|
||||
export const getMDirects = (mDirectEvent: MatrixEvent): Set<string> => {
|
||||
const roomIds = new Set<string>();
|
||||
|
||||
Reference in New Issue
Block a user