Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
typescript泛型中的自定义枚举过于复杂_Typescript_Enums_Typescript Generics - Fatal编程技术网

typescript泛型中的自定义枚举过于复杂

typescript泛型中的自定义枚举过于复杂,typescript,enums,typescript-generics,Typescript,Enums,Typescript Generics,如果有更简单的方法写下来,因为这是非常重复的,只是看起来非常错误 const FolderVisibility = new Enum<{ PUBLIC: 'public', PRIVATE: 'private' }>({ PUBLIC: 'public', PRIVATE: 'private' }) as Enum<{ PUBLIC: 'public', PRIVATE: 'private' }> & { P

如果有更简单的方法写下来,因为这是非常重复的,只是看起来非常错误

const FolderVisibility = new Enum<{
    PUBLIC: 'public',
    PRIVATE: 'private'
}>({
    PUBLIC: 'public',
    PRIVATE: 'private'
}) as Enum<{
    PUBLIC: 'public',
    PRIVATE: 'private'
}> & {
    PUBLIC: 'public',
    PRIVATE: 'private'
}
关键是,如果我复制构造函数中使用的对象4次,它甚至会告诉我
FolderVisibility.values
的类型是
“public”;“private”

PS:我已经试过了,但是它会给我
FolderVisibility.values的
string
。而且,它仍然相当长。 常数数据={ PUBLIC:“PUBLIC”, 私人:“私人” }

const FolderVisibility=新枚举(数据)作为枚举和数据类型

对象文字和文字类型的问题在于,您无法让编译器推断对象文字属性的文字类型。这就是为什么需要指定泛型类型参数的原因

您的方法中有一部分是绝对可以简化的,那就是枚举后的强制转换。不要使用构造函数,使用简单的函数,因为它可以更灵活地返回:

function Enum<T extends{ [P in keyof T]: string }>(enums: T) {

    let map : { [index: string]: string } = {}

    for (let prop in enums) {
        if (enums.hasOwnProperty(prop)) {
            const value = enums[prop]
            if(typeof value != 'string'){
                throw new EnumError(value)
            }
            map[prop] = value;
        }
    }
    let result = Object.assign({}, enums , {
        values: Object.values(map),
        isValid(text: string) {
            if (!text) return true
            return this.values.includes(text)
        }
    });
    // maybe frees the enum so no values are chanegd ?
    return Object.freeze(result);
}
const FolderVisibility = Enum<{
    PUBLIC: 'public',
    PRIVATE: 'private'
}>({
    PUBLIC: 'public',
    PRIVATE: 'private'
});
console.log(FolderVisibility.isValid("")) // Works
console.log(FolderVisibility.PRIVATE === "private" ) // And const fields of string literal type
或者,我们可以稍微更改
Enun
函数,以接受一个在内部创建枚举的回调,这样就永远不会访问非扩展枚举:

function Enum<T extends{ [P in keyof T]: string }>(enumsCreator: () => T) {
    let enums = enumsCreator();
    …
}

const FolderVisibility = Enum(()=> 
{
    enum FolderVisibility {
        PUBLIC ='public',
        PRIVATE=  'private'
    }
    return FolderVisibility;
});
函数枚举(enumsCreator:()=>T){
设enums=enumsCreator();
…
}
常量FolderVisibility=Enum(()=>
{
枚举文件夹可见性{
“公众”,
PRIVATE='PRIVATE'
}
返回文件夹可见性;
});

对象文字和文字类型的问题在于,您无法让编译器推断对象文字属性的文字类型。这就是为什么需要指定泛型类型参数的原因

您的方法中有一部分是绝对可以简化的,那就是枚举后的强制转换。不要使用构造函数,使用简单的函数,因为它可以更灵活地返回:

function Enum<T extends{ [P in keyof T]: string }>(enums: T) {

    let map : { [index: string]: string } = {}

    for (let prop in enums) {
        if (enums.hasOwnProperty(prop)) {
            const value = enums[prop]
            if(typeof value != 'string'){
                throw new EnumError(value)
            }
            map[prop] = value;
        }
    }
    let result = Object.assign({}, enums , {
        values: Object.values(map),
        isValid(text: string) {
            if (!text) return true
            return this.values.includes(text)
        }
    });
    // maybe frees the enum so no values are chanegd ?
    return Object.freeze(result);
}
const FolderVisibility = Enum<{
    PUBLIC: 'public',
    PRIVATE: 'private'
}>({
    PUBLIC: 'public',
    PRIVATE: 'private'
});
console.log(FolderVisibility.isValid("")) // Works
console.log(FolderVisibility.PRIVATE === "private" ) // And const fields of string literal type
或者,我们可以稍微更改
Enun
函数,以接受一个在内部创建枚举的回调,这样就永远不会访问非扩展枚举:

function Enum<T extends{ [P in keyof T]: string }>(enumsCreator: () => T) {
    let enums = enumsCreator();
    …
}

const FolderVisibility = Enum(()=> 
{
    enum FolderVisibility {
        PUBLIC ='public',
        PRIVATE=  'private'
    }
    return FolderVisibility;
});
函数枚举(enumsCreator:()=>T){
设enums=enumsCreator();
…
}
常量FolderVisibility=Enum(()=>
{
枚举文件夹可见性{
“公众”,
PRIVATE='PRIVATE'
}
返回文件夹可见性;
});

为什么不能使用简单的类型脚本enum
enum FolderVisibilityEnum{PUBLIC='PUBLIC',PRIVATE='PRIVATE'}
?您可以为枚举创建这些方法,这样看起来会更好。我们有多个枚举,它们共享同一个类,因此使用相同的函数似乎是合适的。第二个好处是更好地学习如何在TS中使用泛型类型。有这么多功能,但很难找到它们的教程。为什么不能使用简单的类型脚本enum
enum FolderVisibilityEnum{PUBLIC='PUBLIC',PRIVATE='PRIVATE}
?您可以为枚举创建这些方法,这样看起来会更好。我们有多个枚举,它们共享同一个类,因此使用相同的函数似乎是合适的。另外,如果添加一个枚举不需要太多的努力也很好。第二个好处是更好地学习如何在TS中使用泛型类型。有很多特性,但很难找到它们的教程
function Enum<T extends{ [P in keyof T]: string }>(enumsCreator: () => T) {
    let enums = enumsCreator();
    …
}

const FolderVisibility = Enum(()=> 
{
    enum FolderVisibility {
        PUBLIC ='public',
        PRIVATE=  'private'
    }
    return FolderVisibility;
});