Skip to content

Inline type annotations for destructured properties using angle bracket syntax #58633

Closed

Description

🔍 Search Terms

inline type annotations, type annotations, destructuring annotations, destructuring, property annotations, parameter destructuring,

✅ Viability Checklist

⭐ Suggestion

I've observed a lot of discussion around the verbosity/duplication involved when providing type annotations for destructured object properties (particularly re-ignited by this Svelte issue), which prompted me to wonder if this could be resolved with additional syntax being introduced to TypeScript.

The proposal suggests introducing new syntax for adding inline type annotations using angle brackets <T> within destructuring assignments that can be added immediately after the property keys, along with a new optional modifier keyword to indicate a property as optional.

e.g. this

// before
function fetchData({
    url,
    method = "GET",
    timeout = 0
}: {
    url: string;
    method?: string;
    timeout?: number;
}) {
    console.log(`Fetching data from ${url} with method ${method} and timeout ${timeout}`);
}

// after
function fetchData({
  url<string>,
  method<optional string> = "GET",
  timeout<optional number> = 0
}) {
  console.log(`Fetching data from ${url} with method ${method} and timeout ${timeout}`);
}

For completeness (though far less valuable), this could probably also support providing annotations in array destructuring assignments as well. e.g.

// before
function processCoordinates([x, y, z]: [number, number, number]) {
  console.log(`Coordinates are x: ${x}, y: ${y}, z: ${z}`);
}

// after
function processCoordinates([x<number>, y<number>, z<number>]) {
  console.log(`Coordinates are x: ${x}, y: ${y}, z: ${z}`);
}

Advantages:

  1. Readability when destructuring is improved as the types are colocated directly next to each of the destructured properties.
  2. Less verbose/redundancy as you don't have to declare destructured properties twice.

Drawbacks:

  1. The angle bracket syntax might introduce more confusion to understanding TypeScript syntax, given it is already being used for both generics and type casting.
  2. This is a non-backwards compatible breaking change to TypeScript.

Other considerations:

  1. Should the optional modifier keyword also work inside of object literal types.
  2. Could a ? be used instead of the new optional modifier inside/outside of the brackets (e.g. url?<string> or url<string?>). Would probably be more familiar to the way optional properties are defined now, but it might get confusing whether ? is part of the property name in the first example, or part of conditional logic in the second.

📃 Motivating Example

Drawing inspiration from the Svelte $props issue linked above, a React equivalent example might look like:

// before
const Button = ({
  label,
  size = 'medium',
  onClick,
  disabled = false
}: {
  label: string;
  size?: 'small' | 'medium' | 'large';
  onClick?: () => void;
  disabled?: boolean;
}) => {
  return (
    <button 
      className={`btn ${size}`} 
      onClick={onClick} 
      disabled={disabled}
    >
      {label}
    </button>
  );
};

// after
const Button = ({
  label<string>,
  size<optional 'small' | 'medium' | 'large'> = 'medium',
  onClick<optional () => void>,
  disabled<optional boolean> = false
}) => {
  return (
    <button 
      className={`btn ${size}`} 
      onClick={onClick} 
      disabled={disabled}
    >
      {label}
    </button>
  );
};

💻 Use Cases

  1. What do you want to use this for?

Reducing duplication whenever needing to do destructuring assignments with type annotations. In particular it will solve the Svelte issue linked above, but applies anywhere you use destructuring and type annotations that you commonly see with function arguments.

  1. What shortcomings exist with current approaches?

As discussed above already, it's unnecessarily verbose and duplicative, and prevents the colocation of types where you probably want to see them.

  1. What workarounds are you using in the meantime?

Move the type declarations for destructured function params above/outside of the destructuring assignment, but this isn't actually addressing the problems solved by the new syntax.

Activity

  1. whzx5byb commented on May 23, 2024

    @whzx5byb

    Related: #29526.

  2. Not-Jayden commented on May 23, 2024

    @Not-Jayden
    Author

    Thanks whzx5byb, will close as a duplicate

  3. fatcerberus commented on May 23, 2024

    @fatcerberus

    Related: #29526.

    Wow that comment thread turned into a trainwreck at the end there. It seems to have completely devolved to “why you just shouldn’t use destructuring at all, and then you won’t need this feature” which is just… not productive at all

  4. locked as resolved and limited conversation to collaborators on Oct 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions