Meta / Pyrefly
Merged via Meta CodeSyncCorrectnessMerged Jun 23, 2026

Fix TypedDict literal defaults for get/pop

Fixed Pyrefly's TypedDict method synthesis so literal defaults passed to get/pop preserve the field's precise type when the default is already assignable to that field.

facebook/pyrefly · #3831

Problem

For a non-required TypedDict field typed as a Literal union, data.get("key", "value2") could resolve to Literal["value1", "value2"] | str. The default literal was flowing through the generic default overload, widening an already-valid field default into a less precise string type.

Approach

Added a field-typed default overload before the generic default overload when synthesizing TypedDict get/pop methods, so defaults assignable to the field type return the field type while incompatible defaults keep the existing FieldType | T behavior.

Impact and scope

  • Improves Pyrefly's type precision for Python code that uses NotRequired TypedDict fields with literal defaults.
  • Reduces false-positive type widening in common config, state, and structured-dictionary access patterns.
  • Preserves existing fallback behavior for defaults outside the field type by keeping the generic overload after the precise overload.

Validation

  • Added test_get_not_required_literal_default with assert_type coverage for NotRequired[Literal[...]] and a literal default.
  • PR validation covered cargo fmt plus focused Pyrefly tests for the new regression, get behavior, and pop behavior.
  • Landed as Meta CodeSync commit b2f67a7 with author goutamadwant and PR #3831 referenced in the public commit message.