diff --git a/src/streamed/events.ts b/src/streamed/events.ts new file mode 100644 index 000000000..78e4fa191 --- /dev/null +++ b/src/streamed/events.ts @@ -0,0 +1,43 @@ +import { Contract, EventData } from "web3-eth-contract" +import { ContractEvent } from "../../build/types/types" + +/** + * Event type specified by name. + */ +type Event< + C extends Contract, + T extends Exclude, +> = EventMetadata & EventDiscriminant + +/** + * Concrete event type with known properties based on the event name. + * + * @remarks + * This type definition allows the TypeScript compiler to determine the type of + * the `returnValues` property based on `event` property checks. For example: + * ``` + * const eventData: AnyEvent = ... + * case "Token": // ERR: 2678: Type '"Token"' is not comparable to type + * // '"OrderPlacement" | "TokenListing" | ...' + * break + * case "OrderPlacement": + * eventData.returnValues.buyToken = "asdf" // OK + * break + * case "Withdraw": + * eventData.returnValues.buyToken = "asdf" // ERR: 2339: Property 'buyToken' does not exist on type + * // '{ user: string; token: string; amount: string; ... }'. + * break + * } + * ``` + */ +type AnyEvent = EventMetadata & EventDiscriminant> + +type EventMetadata = Omit +type EventValues = T extends ContractEvent ? U : never +type EventDiscriminant< + C extends Contract, + T extends Exclude, +> = T extends any ? { + event: T, + returnValues: EventValues, +} : never