json-typescript-mapper icon indicating copy to clipboard operation
json-typescript-mapper copied to clipboard

Support for Enum

Open LarsLiden opened this issue 8 years ago • 6 comments

Is there a way to support enum?

https://www.typescriptlang.org/docs/handbook/enums.html

LarsLiden avatar Jul 06 '17 00:07 LarsLiden

If your enum is a string enum, this will work out-of-the-box without any clazz. I just verified.

abobwhite avatar May 10 '18 16:05 abobwhite

Using a string enum works for serializing, but not deserializing.

evergreen-lee-campbell avatar Aug 28 '18 14:08 evergreen-lee-campbell

Isn't this a limitation of Typescript string enums? An enum would come in as a string request but cannot be reverse mapped to its member.

cantide5ga avatar Oct 18 '18 20:10 cantide5ga

If I specify that it should be mapped to my enum's clazz, I'd like to be able to reverse map to the member (as you might with, say, the EnumMember decoration in C#).

evergreen-lee-campbell avatar Oct 19 '18 08:10 evergreen-lee-campbell

Maybe try https://github.com/typestack/class-transformer. I prefer that solution to this one anyway, however, I haven't yet tried enums with it

abobwhite avatar Oct 19 '18 11:10 abobwhite

I think it's important to repeat that Typescript itself cannot reverse map an enum based on a string.

One workaround my colleague @imperialyoyo implemented was through a converter:

export const getEnumConverter = (stringEnum: StringEnum, name: string): ICustomConverter => {
    return {
        fromJson(data) {
            if (isArrayOrArrayClass(data)) {
                return (data as string[])
                    .map((dataElement) => getEnumMatch(stringEnum, dataElement, name));
            } else {
                return getEnumMatch(stringEnum, data, name);
            }
        },
        toJson(data) {
            if (isArrayOrArrayClass(data)) {
                return (data as string[]).map((dataElement) => dataElement.toString());
            } else {
                return data ? data.toString() : null;
            }
        }
    };
};

const getEnumMatch = (stringEnum: StringEnum, data: string, name: string) => {
    if (data == null) {
        return null;
    }
    if (stringEnum[data]) {
        return stringEnum[data];
    }
    const enumValueMatch = getEnumValueMatch(stringEnum, data);
    if (enumValueMatch) {
        return enumValueMatch;
    }
    return data;
};

const getEnumValueMatch = (stringEnum: StringEnum, data: string): string => {
    const enumPropertyNames = Object.getOwnPropertyNames(stringEnum);
    const foundReverseSearch = enumPropertyNames.map((property) => stringEnum[property]).indexOf(data);
    if (foundReverseSearch > -1) {
        return stringEnum[enumPropertyNames[foundReverseSearch]];
    } else {
        return null;
    }
};

cantide5ga avatar Oct 25 '18 18:10 cantide5ga