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)
>Solution :
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.