0

type StringTyped = {[key: string]: any};

type ShouldBeStringType = keyof StringTyped;
const test:ShouldBeStringType = 2; // but this is allowed?

I am trying to have a generic Type that relies on keyof actually returning the type which is specified, but keyof seems to always return the type string | number, even if I specify beforehand, that the keys of the object are strings.

type StringTyped = {[key: string]: any};

class Emitter<T extends StringTyped> {
    emit<K extends keyof T>(socket: Socket, event: K, data: T[K]): void {
        socket.emit(event, data);
    }
    broadcast<K extends keyof T>(io: Server, room: string, event: K, data: T[K]): void {
        io.to(room).emit(event, data);
    }
    broadcastAll<K extends keyof T>(io: Server, event: K, data: T[K]): void {
        io.emit(event, data);
    }
}

I am trying to streamline socket-io with a wrapper and the reason I need the return type of keyof to be a string is that event has to be a string. The question is how to make this work or if there is a better way to type key and value pairs as paramater.

I tried to just use event.toString() when event is needed, but the .toString() could be overwritten to then execute some arbitrary code and could maybe lead to a security issue. (not if this concern is really valid)

jimmyfan
  • 53
  • 5

1 Answers1

1

If you want to enforce the type ShouldBeStringType as a string, you can use the following:

type ShouldBeStringType = keyof StringTyped & string;

This answer is borrowed from here, originally by madox2.

Aaron Meese
  • 1,670
  • 3
  • 22
  • 32