diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py
--- a/mypy/checkexpr.py
+++ b/mypy/checkexpr.py
@@ -2910,9 +2910,11 @@ def visit_index_with_type(self, left_type: Type, e: IndexExpr,
 
         if isinstance(left_type, UnionType):
             original_type = original_type or left_type
+            # Don't combine literal types, since we may need them for type narrowing.
             return make_simplified_union([self.visit_index_with_type(typ, e,
                                                                      original_type)
-                                          for typ in left_type.relevant_items()])
+                                          for typ in left_type.relevant_items()],
+                                         contract_literals=False)
         elif isinstance(left_type, TupleType) and self.chk.in_checked_function():
             # Special case for tuples. They return a more specific type when
             # indexed by an integer literal.

diff --git a/test-data/unit/check-narrowing.test b/test-data/unit/check-narrowing.test
--- a/test-data/unit/check-narrowing.test
+++ b/test-data/unit/check-narrowing.test
@@ -1029,3 +1029,26 @@ else:
     reveal_type(str_or_bool_literal)  # N: Revealed type is "Union[Literal[False], Literal[True]]"
 
 [builtins fixtures/primitives.pyi]
+
+[case testNarrowingTypedDictUsingEnumLiteral]
+from typing import Union
+from typing_extensions import TypedDict, Literal
+from enum import Enum
+
+class E(Enum):
+    FOO = "a"
+    BAR = "b"
+
+class Foo(TypedDict):
+    tag: Literal[E.FOO]
+    x: int
+
+class Bar(TypedDict):
+    tag: Literal[E.BAR]
+    y: int
+
+def f(d: Union[Foo, Bar]) -> None:
+    assert d['tag'] == E.FOO
+    d['x']
+    reveal_type(d)  # N: Revealed type is "TypedDict('__main__.Foo', {'tag': Literal[__main__.E.FOO], 'x': builtins.int})"
+[builtins fixtures/dict.pyi]

TypedDict narrowing regression with enum literal
The following example started generating a false positive after #9097:

```py
from typing import TypedDict, Literal, Union
from enum import Enum

class E(Enum):
    FOO = "a"
    BAR = "b"

class Foo(TypedDict):
    tag: Literal[E.FOO]
    x: int

class Bar(TypedDict):
    tag: Literal[E.BAR]
    y: int

def f(d: Union[Foo, Bar]) -> None:
    assert d['tag'] == E.FOO
    d['x']  # TypedDict "Bar" has no key "x"
```

Type narrowing should work and there should be no error reported.

mypy/test/testcheck.py::TypeCheckSuite::testNarrowingTypedDictUsingEnumLiteral