11// Copyright (c) Microsoft Corporation.
22// Licensed under the MIT License.
33
4- import { world , system } from '@minecraft/server' ;
4+ import { SystemAfterEvents , WorldAfterEvents } from '@minecraft/server' ;
55
66/**
77 * A promise wrapper utility which returns a new promise that will resolve when the next
@@ -49,25 +49,33 @@ export interface EventPromise<T> extends Promise<T | undefined> {
4949 finally ( onfinally ?: ( ( ) => void ) | null ) : Promise < T | undefined > ;
5050}
5151
52+ /**
53+ * The keys of after event signals that exist in Minecraft's API that EventPromise can use.
54+ *
55+ * @public
56+ */
57+ export type MinecraftAfterEventSignalKeys = keyof WorldAfterEvents | keyof SystemAfterEvents ;
5258/**
5359 * The types of after event signals that exist in Minecraft's API that EventPromise can use.
5460 *
5561 * @public
5662 */
57- export type MinecraftAfterEventSignals =
58- | ( typeof world . afterEvents ) [ keyof typeof world . afterEvents ]
59- | ( typeof system . afterEvents ) [ keyof typeof system . afterEvents ] ;
63+ export type MinecraftAfterEventSignals < K extends MinecraftAfterEventSignalKeys > = K extends keyof WorldAfterEvents
64+ ? WorldAfterEvents [ K ]
65+ : K extends keyof SystemAfterEvents
66+ ? SystemAfterEvents [ K ]
67+ : never ;
6068
6169/**
6270 * Helper to create a new EventPromise from an after event signal.
6371 *
6472 * @public
6573 */
66- export function nextEvent < U > (
67- signal : MinecraftAfterEventSignals ,
68- filter ?: U
69- ) : EventPromise < Parameters < Parameters < typeof signal . subscribe > [ 0 ] > [ 0 ] > {
70- return new EventPromiseImpl < Parameters < Parameters < typeof signal . subscribe > [ 0 ] > [ 0 ] , U > ( signal , filter ) ;
74+ export function nextEvent < T extends MinecraftAfterEventSignals < MinecraftAfterEventSignalKeys > > (
75+ signal : T ,
76+ filter ?: Parameters < T [ 'subscribe' ] > [ 1 ]
77+ ) : EventPromise < Parameters < ReturnType < T [ 'subscribe' ] > > [ 0 ] > {
78+ return new EventPromiseImpl ( signal , filter ) ;
7179}
7280
7381/**
@@ -76,32 +84,37 @@ export function nextEvent<U>(
7684 *
7785 * @private
7886 */
79- class EventPromiseImpl < T , U > implements Promise < T | undefined > {
87+ class EventPromiseImpl <
88+ K extends MinecraftAfterEventSignalKeys ,
89+ Signal extends MinecraftAfterEventSignals < K > ,
90+ T = Parameters < ReturnType < Signal [ 'subscribe' ] > > [ 0 ] ,
91+ U = Parameters < Signal [ 'subscribe' ] > [ 1 ] ,
92+ > implements EventPromise < T | undefined >
93+ {
8094 [ Symbol . toStringTag ] = 'Promise' ;
8195 private promise : Promise < T | undefined > ;
8296 private onCancel ?: ( ) => void ;
8397
84- constructor ( signal : MinecraftAfterEventSignals , filter ?: U ) {
98+ constructor ( signal : Signal , filter ?: U ) {
8599 this . promise = new Promise < T | undefined > ( ( resolve , _ ) => {
86100 if ( signal === undefined || signal . subscribe === undefined || signal . unsubscribe === undefined ) {
87101 resolve ( undefined ) ;
88102 return ;
89103 }
90104
91- const sub = ( event : T ) => {
105+ const sub = ( event : Parameters < ReturnType < Signal [ 'subscribe' ] > > [ 0 ] ) => {
92106 this . onCancel = undefined ;
93- signal . unsubscribe ( sub as never ) ;
94- resolve ( event ) ;
107+ signal . unsubscribe ( sub ) ;
108+ resolve ( event as T ) ;
95109 } ;
96110 if ( filter === undefined ) {
97- signal . subscribe ( sub as never ) ;
111+ signal . subscribe ( sub ) ;
98112 } else {
99- // eslint-disable-next-line @typescript-eslint/no-explicit-any
100- ( signal . subscribe as ( listener : ( event : T ) => void , filter : U ) => ( ...a : any ) => void ) ( sub , filter ) ;
113+ ( signal . subscribe as ( handler : Parameters < Signal [ 'subscribe' ] > [ 0 ] , filter : U ) => void ) ( sub , filter ) ;
101114 }
102115
103116 this . onCancel = ( ) => {
104- signal . unsubscribe ( sub as never ) ;
117+ signal . unsubscribe ( sub ) ;
105118 resolve ( undefined ) ;
106119 } ;
107120 } ) ;
0 commit comments