Skip to content

Const primitive value type getting lost? #48402

Closed
@TeoTN

Description

@TeoTN

Bug Report

It seems to me that type for primitive value assigned to a const variable gets widened in some contexts - I'm not 100% sure if this is a bug report or feature request, but this is a bit counterintuitive. Is this an expected behaviour?
(From what I saw in the playground hints, primitive values assigned to const behave as if they had as const modifier)

🔎 Search Terms

primitive value
primitive widening

⏯ Playground Link

Playground link with relevant code

💻 Code

The hint shows the TYPE_1 is not string:
Screenshot 2022-03-24 at 18 04 34

const TYPE_1 = 'TYPE_1';
const TYPE_2 = 'TYPE_2';
const TYPE_3 = 'TYPE_3' as const;
const TYPE_4 = 'TYPE_4' as const;

const action1 = () => ({ type: TYPE_1 });
const action2 = () => ({ type: TYPE_2, payload: {} });
const action3 = () => ({ type: TYPE_3 });
const action4 = () => ({ type: TYPE_4, payload: {} });

type NonConstTypeActions =
  | ReturnType<typeof action1>
  | ReturnType<typeof action2>
;

type ConstTypeActions =
  | ReturnType<typeof action3>
  | ReturnType<typeof action4>
;

function nonConstTypesReducer(state: {}, action: NonConstTypeActions) {
  switch (action.type) {
    case TYPE_2:
      return action.payload; // Property 'payload' does not exist on type 'NonConstTypeActions'.
    default:
      return {};
  }
}

function withConstTypesReducer(state: {}, action: ConstTypeActions) {
  switch (action.type) {
    case TYPE_4:
      return action.payload;
    default:
      return {};
  }
}

🙁 Actual behavior

Type guard wasn't able to narrow down a type because field type got widened to string.

🙂 Expected behavior

Both examples should pass

Metadata

Metadata

Assignees

No one assigned

    Labels

    QuestionAn issue which isn't directly actionable in code

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions