Tested on TypeScript 3.9.7
Solution
type EnumTypeString<TEnum extends string> =
    { [key in string]: TEnum | string; }
type EnumTypeNumber<TEnum extends number> =
    { [key in string]: TEnum | number; }
    | { [key in number]: string; }
type EnumType<TEnum extends string | number> =
    (TEnum extends string ? EnumTypeString<TEnum> : never)
    | (TEnum extends number ? EnumTypeNumber<TEnum> : never)
type EnumOf<TEnumType> = TEnumType extends EnumType<infer U>
    ? U
    : never
Usage
EnumType:
function forEachEnum<TEnum extends string | number>(
    enumType: EnumType<TEnum>,
    callback: (value: TEnum, key: string) => boolean|void,
) {
    for (let key in enumType) {
        if (Object.prototype.hasOwnProperty.call(enumType, key) && isNaN(Number(key))) {
            const value = enumType[key] as any
            if (callback(value, key)) {
                return
            }
        }
    }
}
EnumOf:
function forEachEnum2<TEnumType>(
    enumType: TEnumType,
    callback: (value: EnumOf<TEnumType>, key: string) => boolean|void,
) {
    for (let key in enumType) {
        if (Object.prototype.hasOwnProperty.call(enumType, key) && isNaN(Number(key))) {
            const value = enumType[key] as any
            if (callback(value, key)) {
                return
            }
        }
    }
}
Tests
enum EnumAsString {
    Value1 = 'value 1',
    Value2 = 'value 2',
}
enum EnumAsNumber {
    Value1 = 1,
    Value2 = 2,
}
// Error
let sn: EnumType<string> = EnumAsNumber
// Correct
let ns: EnumType<number> = EnumAsString // I have not found a solution for the error here
let nn: EnumType<number> = EnumAsNumber
let Nn: EnumType<EnumAsNumber> = EnumAsNumber
let ss: EnumType<string> = EnumAsString
let Ss: EnumType<EnumAsString> = EnumAsString
forEachEnum(EnumAsString, value => {
    let e: EnumAsString = value
    let s: string = value
    let n: number = value // Error
})
forEachEnum(EnumAsNumber, value => {
    let e: EnumAsNumber = value
    let s: string = value // Error
    let n: number = value
})
forEachEnum2(EnumAsString, value => {
    let e: EnumAsString = value
    let s: string = value
    let n: number = value // Error
})
forEachEnum2(EnumAsNumber, value => {
    let e: EnumAsNumber = value
    let s: string = value // Error
    let n: number = value
})