Skip to content

Type-safe const assertionsΒ #42234

@btoo

Description

@btoo

Suggestion

πŸ” Search Terms

type-safe const assertions

βœ… Viability Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals.

⭐ Suggestion

By allowing const assertions to accept a type, they can statically validate the type of the value during construction, thereby providing the benefit of both standard and const assertions at the same time:

  • literalExpression as const Type
  • <const Type>literalExpression

where literalExpression is the literal expression whose type is being derived and Type is the type against which the derived type is going to be checked for extends

πŸ“ƒ Motivating Example

type WeekDay = 'm' | 'tu' | 'w' | 'th' | 'f';
const mondayAndTuesday = ['m', 'tu'] as const WeekDay[]; // needs to not error
type ConstAssertion1 = typeof mondayAndTuesday extends WeekDay[] ? true : false; // true
type ConstAssertion2 = typeof mondayAndTuesday extends readonly ['m', 'tu'] ? true : false; // true
const mondayTuesdayAndSaturday = ['m', 'tu', 'sa'] as const WeekDay[]; // needs to error

This should also make it possible to allow autocomplete suggestions when literalExpression as const WeekDay[] is being written

πŸ’» Use Cases

I often find myself having to choose between using a standard type assertion and using a const assertion. Both offer important capabilities for static analysis:

  • Standard: Assert that the type of the value being constructed extends SomePreexistingType
    • e.g.
      type WeekDay = 'm' | 'tu' | 'w' | 'th' | 'f';
      'sa' as WeekDay; // correctly errors
  • const: Prevent type-widening of the value being constructed
    • e.g.
      const weekDays = ['m', 'tu', 'w', 'th', 'f'] as const;
      weekDays.filter(weekDay => weekDay === 'sa'); // correctly errors

However, there isn't a way to have them both (at least not without a runtime assertion function, it seems)

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions