Rust enums are represented in TS as a type union. For some reason, T extends null collapses the type into an intersection, which makes it a type error to call SomeEvent.emit(x) for any value x. That may be a TypeScript error—I'm still investigating. In the meantime, this patch avoids the issue.
Here's a minimal example to try in the typescript playground. The definition of __EventObj__ is as it is before my patch.
// These definitions come from @tauri-apps/api/event
interface Event<T> {
/** Event name */
event: EventName;
/** Event identifier used to unlisten */
id: number;
/** Event payload */
payload: T;
}
declare function emit(event: string, payload?: unknown): Promise<void>;
type EventCallback<T> = (event: Event<T>) => void;
type EventName = string & Record<never, never>
// This is generated by tauri-specta based on my rust types
export type SocketAction =
| { MessageForClient: { conn_id: string; message: string } }
| { CloseSocket: { conn_id: string } }
// This is also from tauri-specta, but doesn't depend on my types
type __EventObj__<T> = {
emit: T extends null
? (payload?: T) => ReturnType<typeof emit>
: (payload: T) => ReturnType<typeof emit>
}
// pretend we have one of these
declare const eo: __EventObj__<SocketAction>;
const x = { MessageForClient: { conn_id: 'string', message: 'str' }} satisfies SocketAction
eo.emit(x) // 💥 Type error
Rust enums are represented in TS as a type union. For some reason,
T extends null
collapses the type into an intersection, which makes it a type error to callSomeEvent.emit(x)
for any value x. That may be a TypeScript error—I'm still investigating. In the meantime, this patch avoids the issue.Here's a minimal example to try in the typescript playground. The definition of
__EventObj__
is as it is before my patch.