I'm creating an event system in Unity Tiny because the one in the framework itself is very limited. I got it working but now I would like to make it more userfriendly for my colleagues. So I tried to typeguard it to prevent users from using different types but it does not seem to work for me. Any suggestions?
I already looked at these: - https://medium.com/ovrsea/checking-the-type-of-an-object-in-typescript-the-type-guards-24d98d9119b0 - https://dev.to/krumpet/generic-type-guard-in-typescript-258l
The problem is that unity tiny is using es5. So you can't get the object.construtor.name to get the name of a type. Therefor using "instanceof" isn't possible.
Also, the (object as T) does not work and I could not get the (object as T).type either.
export class Event<T> implements IEvent<T>{
private handlers: {(data?: T): void}[] = [];
public type : T;
constructor(value: T){
this.type = value;
}
public On(handler: { (data?: T): void }) : void {
this.handlers.push(handler);
}
public Off(handler: { (data?: T): void }) : void {
this.handlers = this.handlers.filter(h => h !== handler);
}
public Trigger(data?: T) {
this.handlers.slice(0).forEach(h => h(data));
}
public Expose() : IEvent<T> {
return this;
}
}
export class EventUtils {
public static events = new Object();
public static CreateEvent<T>(eventEntity: ut.Entity, nameOfEvent: string) : void{
this.events[nameOfEvent] = new game.Event<T>();
}
public static Subscribe<T>(nameOfEvent: string, handeler: {(data? : T): void}) : void{
//Loop through events object, look for nameOfEvent, use checkEventType() to check if it is the same type as given generic, then subscribe if true.
}
public static Trigger<T>(nameOfEvent: string, parameter?: T) : void{
//Loop through events object, look for nameOfEvent, use checkEventType() to check if it is the same type as given generic, then trigger if true.
}
private static checkEventType<T>(object: any) : object is Event<T>{
let temp : T;
let temp2 = {temp};
if (object.type instanceof temp2.constructor.name) {
return true;
}
return false;
}
}
}
private static checkEventType<T>(object: any) : object is Event<T>{
let temp : T;
if (object.type as typeof temp) {
return true;
//always returns true even if the type is different
}
return false;
}
}
and
let temp : T;
if ((object.type as typeof temp).type) {
return true;
//property 'type' does not exist in 'T'
}
return false;
instanceof
exists and has been supported for a while so you can use it even in ES5.
The only problem is the way you are doing your check. If you need to check for an instance of a class you need to actually have the class (not just the type) in the checkEventType
function:
public static checkEventType<T>(cls: new (...a: any[]) => T, object: any): object is Event<T> {
if (object.type instanceof cls) {
return true;
}
return false;
}