I want to use "constant" variables in my typing definitions, something like this: FOO = "foo" BAR = "bar" @dataclass class Event(): name: Literal[FOO, BAR] But that is illegal code for mypy. This works, but then I cannot use the variables in my code: FOO = Literal["foo"] BAR = Literal["bar"] @dataclass class Event(): name: FOO | BAR Event(FOO) # gives: Event(name=typing.Literal['foo']) Is there a way to get this to work without defining FOO and BAR twice? Impelenting Marks answer (https://stackoverflow.com/a/76382060/5386216) works, but then mypy is not able to distinguish types based on the event name: class FooBar(Enum): FOO = "foo" BAR = "bar" @dataclass class StringEvent: name: Literal[FooBar.FOO] value: str @dataclass class NumberEvent: name: Literal[FooBar.BAR] value: int def handle_event(event: StringEvent | NumberEvent): if event.name == FooBar.FOO: event.value.upper() # should not give a mypy error if event.name == FooBar.BAR: event.value.upper() # Should give a mypy error Both both cases of event.value.upper() give the following mypy error: Item "int" of "Union[str, int]" has no attribute "upper" Continue reading...