pydantic-to-typescript icon indicating copy to clipboard operation
pydantic-to-typescript copied to clipboard

Enums used as `Dict` keys are lost when converted to TS

Open talyh opened this issue 2 years ago • 1 comments

Hello. Thanks for this package, it makes our lives a lot easier in keeping definitions consistent across BE and FE repos.

One challenge we've been been facing is with loss of information when it comes to restricted keys in dictionaries.

For instance

example_attribute: Dict[ProvinceEnum,str]

becomes

example_attribute: {
    [k: string]: string;
  };

which means any string is a valid key, not just the ones defined within the enum.

Is there a different Pydantic representation that would be better suited to produce a more restrictive TS version? Or is this a gap in the code generation?

talyh avatar Mar 11 '22 05:03 talyh

Hi @talyh, good question!

I think we can make that happen if we do a bit of trickery with TypedDict. It lets you define a restricted set of keys, and if you pass the total=False parameter in the constructor it considers any subset of those keys to be valid. (As opposed to requiring that all keys be present). https://docs.python.org/3/library/typing.html#typing.TypedDict

For example, I just tried out this little enum_map helper to dynamically generate restricted mapping types. If you have the following models:

class ProvinceEnum(str, Enum):
    foo = "foo"
    bar = "bar"


def enum_map(keys: Type[Enum], value_type: type) -> Type[TypedDict]:
    name = f"Map{keys.__name__}To{value_type.__name__.title()}"
    return TypedDict(name, {x.value: value_type for x in keys}, total=False)


class Example(BaseModel):
    example_attribute: enum_map(ProvinceEnum, str)

These are the definitions generated by pydantic-to-typescript:

export interface Example {
  example_attribute: MapProvinceEnumToStr;
}
export interface MapProvinceEnumToStr {
  foo?: string;
  bar?: string;
}

Hopefully that helps!

phillipdupuis avatar Aug 11 '22 18:08 phillipdupuis

Hello Thanks for the tip. We'll give it a shot with our own enums

talyh avatar Sep 15 '22 20:09 talyh