Skip to content

Improve Function Signature Syntax #29019

Closed
@Enteleform

Description

@Enteleform

Suggestion

Please reconsider combining default parameters & type annotations in function signatures. This was already proposed in #7576, but the issue was closed shortly after @mhegazy's post which made the following argument:

ultimately, every new syntax added is added complexity, for the user to learn and recognize, and for the compiler code base to maintain, so usually we try to limit complexity unless the value warrants it. and for destructuring, the syntax is already complex to start with, and we did not want to add yet another layer on top.

However, in reality the current syntax is more difficult to write & maintain than the proposed syntax. I'd argue that the proposed syntax would even be worth admitting into Breaking Changes in the long run, given that the change is timed & documented appropriately (even if that means waiting for a major version release).

Examples

//####################//
//###  Assertions  ###//
//####################//

                  //  [arg_1, arg_2, arg_3]
  foo()           //  [0,     0,     0    ]
  foo({})         //  [0,     0,     0    ]
  foo({arg_1:1})  //  [1,     0,     0    ]
  
  
//#####################################//
//###  Proposed Function Signature  ###//
//#####################################//

  // easy to parse
  // easy to maintain
  
    function foo({arg_1:number=0, arg_2:number=0, arg_3:number=0}){
      // ...
    }
    
    function foo({
      arg_1: number = 0,
      arg_2: number = 0,
      arg_3: number = 0,
    }){
      // ...
    }


//####################################//
//###  Current Function Signature  ###//
//####################################//
  
  // difficult to parse
  // difficult to maintain (redundant code)
    
    function foo({arg_1=0, arg_2=0, arg_3=0}:{arg_1?:number, arg_2?:number, arg_3?:number}={}){
      // ...
    }
      
    function foo(
      {arg_1=0, arg_2=0, arg_3=0}
      :{arg_1?:number, arg_2?:number, arg_3?:number}
      ={}
    ){
      // ...
    }
  
  
  // ok to parse
  // difficult to maintain (redundant code, formatting is time consuming)
  
    function foo(
      {arg_1=0,       arg_2=0,       arg_3=0      }:
      {arg_1?:number, arg_2?:number, arg_3?:number}={}
    ){
      // ...
    }


  // ok to parse
  // difficult to maintain (redundant code)
  // 
  // This is currently the most balanced option for [writability, readability, maintainability],
  // but results in double the lines of code; which quickly adds up to 100s or 1000s
  // of lines of unnecessary code in a larger project. This boilerplate creates extra work
  // & detracts from TypeScript's developer experience by forcing developers to spend extra time
  // crafting & tweaking function signatures instead of writing more pertinent code.
  
    function foo({
      arg_1 = 0,
      arg_2 = 0,
      arg_3 = 0,
    }:{
      arg_1?: number,
      arg_2?: number,
      arg_3?: number,
    }={}){
      // ...
    }

Note

A few people have mentioned that there may be a conflict with the {a:b=c} syntax. However, the exact syntax is not the purpose of this recommendation, and I invite any suggestions for a more preferable syntax that does not have any compatibility issues. The important part of this suggestion is that the syntax should be able to handle type annotations & default parameters in one section instead of two.

Search Terms

destructuring destructure function signature default parameters type annotations

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions