question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Object key signature is not taken into account with destructive assignment on method definition level

See original GitHub issue

TypeScript Version: 2.3.2

Code

interface IMyInterface {
  onChange(changes : {[key : string] : {newValue : any, oldValue : any}})
}

class MyClass implements IMyInterface {
  onChange({config}) {
    console.log(config);
  }
}

class MyAnotherClass implements IMyInterface {
  onChange(changes) {
    const {config} = changes;

    console.log(config);
  }
}

Expected behavior: compiled without errors

Actual behavior:

test.ts(5,7): error TS2420: Class 'MyClass' incorrectly implements interface 'IMyInterface'.
  Types of property 'onChange' are incompatible.
    Type '({config}: { config: any; }) => void' is not assignable to type '(changes: { [key: string]: { newValue: any; oldValue: any; }; }) => any'.
      Types of parameters '__0' and 'changes' are incompatible.
        Type '{ [key: string]: { newValue: any; oldValue: any; }; }' is not assignable to type '{ config: any; }'.
          Property 'config' is missing in type '{ [key: string]: { newValue: any; oldValue: any; }; }'.

Note: this affects Angular >1.5 users when writing component controllers and implementing $onChanges method

Issue Analytics

  • State:open
  • Created 6 years ago
  • Comments:14 (9 by maintainers)

github_iconTop GitHub Comments

1reaction
mhegazycommented, May 8, 2017

IMyInterface.onChange says it can be called by any object, as long as its properties have a certain type.

MyClass.onChange has a stricter requirement, saying it has to be called with an object with a property called config.

as a result MyClass is not substituatble for IMyInterface.

The second class MyAnotherClass, says it can be called with any arguments, no requirements here…

If MyClass.onChange does not care if change is not provided, consider making it optional:

class MyClass implements IMyInterface {
  onChange({config = undefined}) {
    console.log(config);
  }
}

or give it an explicit type:

class MyClass implements IMyInterface {
  onChange({config} : any) {
    console.log(config);
  }
}

you can always give type, and you would see a similar error.

class MyAnotherClass implements IMyInterface {
    onChange(changes: { config: number }) {
        const { config } = changes;

        console.log(config);
    }
}
0reactions
sandersncommented, May 8, 2017

Since this is comparing assignability of parameters, there is bivariance. So it shouldn’t be an error.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Destructuring assignment - JavaScript - MDN Web Docs
The destructuring assignment syntax is a JavaScript expression that makes it possible to unpack values from arrays, or properties from ...
Read more >
Destructuring Mixed Objects and Function Arguments in ES6
Learn more ways to destructure mixed objects in and function arguments using JavaScript, HTML, and ES6 in this JS tutorial.
Read more >
Destructuring assignment - The Modern JavaScript Tutorial
Destructuring assignment is a special syntax that allows us to “unpack” arrays or objects into a bunch of variables, as sometimes that's ...
Read more >
JavaScript object destructuring usages you must know
Here, we use the object's key names to create variables and assign them with the value from the object for the same key....
Read more >
Anonymous Types | Microsoft Learn
Anonymous types in C# encapsulate a set of read-only properties in an object without having to explicitly define a type.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found