Description
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