Skip to content

Proposal: Support typedef with assert constraints for refined/validated primitive types #4530

@folaoluwafemi

Description

@folaoluwafemi

Title

Proposal: Support typedef with assert constraints for refined/validated primitive types

Description

I'd like to propose a new language feature that extends Dart's typedef to allow type definitions with built-in assertions — effectively enabling developers to create refined primitive types that can enforce domain constraints at compile time or runtime.

Motivation

Currently, typedef in Dart only provides a type alias and does not allow additional validation logic. Developers often end up writing redundant wrapper classes or validation utilities for simple constraints on primitives like String, int, etc.

This feature would make it possible to define domain-specific primitive types directly at the type level, with associated validation logic.

Example

typedef SupportedUsername = String assert (value) => [
  'username1', 'username2', 'username3'
].contains(value);

typedef PositiveInt = int assert (value) => value > 0;

void registerUser(SupportedUsername username) {
  // username is guaranteed to be one of the supported values
}

How It Works

  • A typedef may include an assert clause that defines validation logic.

  • The assertion is automatically applied:

    • at runtime when a value is assigned (in checked mode)
    • or optionally enforced at compile-time if the value is a constant.
  • This allows developers to define domain-constrained primitives without creating boilerplate wrapper classes.

Benefits

  • Stronger type safety without extra verbosity.
  • Reduces validation boilerplate.
  • Closer alignment with declarative constraints (like SQL CHECK or refined types in functional languages).
  • Improves expressiveness of APIs that rely on domain-specific rules.

Prior Art

  • SQL CHECK constraints
  • TypeScript branded/refined types
  • Haskell & Scala refined types

Example Use Cases

  • Domain-specific constraints: email, UUID, age ≥ 18, non-empty strings
  • Whitelisted enums without needing an enum
  • Safe numeric ranges (e.g. percentages 0–100)

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureProposed language feature that solves one or more problems

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions