title: Typescript incorrect type inference when class implements interface
body: <p>When using composition approach in typescript over inheritance one, I want to describe my entities according to what they "can" and not what they "are". In order to do this I need to create some complex interfaces and then for my classes (I use classes in order not to create manual prototype chain and not break some optimizations that I presume exist inside js engines) to implement my interfaces. But this results in strange behavior when type of a method is not inferred correctly. On the contrary, when using objects and declaring them to be of the same interface type everything works as expected. </p>
  
  <p>So I`m using VSCode with typescript 3.6.3. I`ve created interface for 2d shape that should have method to return all normals to edges. Then I create class that implements that interface and I expect it to require this method and it should have the same return type (this part works) and also same argument types (this one doesn`t). Parameter gets inferred as any. My problem is that I don`t want to create prototype chain by hand only to get consistent VSCode behavior. </p>
  
  <p>Also when running <b>tsc</b> in console I get the same error for parameter being 'any' type in class method and expected error inside object method when accessing non-existent prop</p>
  
  <pre class="lang-js prettyprint-override"><code>interface _IVector2 {
    x: number;
    y: number;
  }
  
  interface _IShape2D {
    getNormals: ( v: string ) =&gt; _IVector2[];
  }
  
  export class Shape2D implements _IShape2D {
    getNormals( v ) {
      console.log( v.g );
                     ^ ----- no error here
  
      return [{} as _IVector2];
    }
  }
  
  export const Test: _IShape2D = {
    getNormals( v ) {
      console.log( v.g );
                     ^------ here we get expected error that  
                     ^------ 'g doesn`t exist on type string'
  
      return [{} as _IVector2];
    }
  };
  </code></pre>
  
  <p>my tsconfig.json</p>
  
  <pre><code>{
    "compilerOptions": {
      "target": "es2017",
      "allowSyntheticDefaultImports": true,
      "checkJs": false,
      "allowJs": true,
      "noEmit": true,
      "baseUrl": ".",
      "moduleResolution": "node",
      "strict": true,
      "strictNullChecks": true,
      "noImplicitAny": true,
      "noUnusedLocals": true,
      "noUnusedParameters": true,
      "noImplicitReturns": true,
      "noImplicitThis": true,
      "noFallthroughCasesInSwitch": true,
      "jsx": "react",
      "module": "commonjs",
      "alwaysStrict": true,
      "forceConsistentCasingInFileNames": true,
      "esModuleInterop": true,
      "noErrorTruncation": true,
      "removeComments": true,
      "resolveJsonModule": true,
      "sourceMap": true,
      "watch": true,
      "skipLibCheck": true,
      "paths": {
        "@s/*": ["./src/*"],
        "@i/*": ["./src/internal/*"]
      }
    },
    "exclude": [
      "node_modules"
    ]
  }
  </code></pre>
  
  <p>Expected:<br/>
  - class method`s parameter should be inferred as string<br/>
  Actual:<br/>
  - method`s parameter is inferred as any</p>
  
  <p>Ultimately my question is as follows:
  "Is this behavior unachievable in ts and I should resort to hand written (oh dear...) prototype chains and simple objects for prototypes?"</p>
  
  <p>Thank you in advance!</p>