Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Object destructuring fails if defaults are set #16355

Closed
jantimon opened this issue Jun 8, 2017 · 4 comments
Closed

Object destructuring fails if defaults are set #16355

jantimon opened this issue Jun 8, 2017 · 4 comments

Comments

@jantimon
Copy link

jantimon commented Jun 8, 2017

TypeScript Version: 2.2.1 / nightly (2.2.0-dev.201xxxxx)
Try it yourself in the playground

Code

function fancyMethod({ option1:boolean = true, option2: number = 1 } = {}) {
    console.log(option1, option2);
}

fancyMethod();
fancyMethod({option2: 3});

Expected behavior:
Console log shows value of option1 and option 2

Actual behavior:
Typescript shows errors:

  • Cannot find name 'option1'.
  • Cannot find name 'option2'.
@ikatyang
Copy link
Contributor

ikatyang commented Jun 8, 2017

I think this is what you want. Object destructuring with type sometime really confuses people.

function fancyMethod({ option1 = true, option2 = 1 }: { option1?: boolean, option2?: number } = {}) {
    console.log(option1, option2);
}
fancyMethod();
fancyMethod({option2: 3});

@jantimon
Copy link
Author

jantimon commented Jun 8, 2017

Thanks I tried this but didn't use it because of #16354

The solution now is:

function fancyMethod({ option1 = true, option2 = 1 }: object & { option1?: boolean, option2?: number } = {}) {
    console.log(option1, option2);
}

If you think of 5 options this becomes very very unreadable and creates maintenance overhead.

Is there any chance to fix it so that the following will work?

function fancyMethod({ option1:boolean = true, option2: number = 1 } = {}) {
    console.log(option1, option2);
}

@ikatyang
Copy link
Contributor

ikatyang commented Jun 8, 2017

This is not a valid TS code, since : in destructuring is considered renaming.

function fancyMethod({ option1: boolean = true, option2: number = 1 } = {}) { // <--
    console.log(option1, option2);
}

Additionally, {} is not assignable to { option1, option2 }, since there is no option1 and option2 in {}.


I think you can use type or interface to simplify the type declaration. For example:

interface X {
  option1?: boolean;
  option2?: number;
}
type NonPrimitive<T> = object & T;

function fancyMethod(x: NonPrimitive<X> = {}) {
  const {
    option1 = true,
    option2 = 1,
  } = x;
  console.log(option1, option2);
}

@jantimon
Copy link
Author

jantimon commented Jun 8, 2017

Unfortunately the interface would be far away from the method as it is a class method.

But thanks to your explanation with the renaming I am now understanding the reason behind it 👍

@jantimon jantimon closed this as completed Jun 8, 2017
@microsoft microsoft locked and limited conversation to collaborators Jun 14, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants