2

Typescript does not detect any error in the code below.

interface testIF {
    test(): void;
    test2(map: Map<string, number>): void
}

function f(): testIF {

    return {
        test: function () {
            let map: Map<string, string> = new Map();
            this.test2(map);                          // Passing Map<string, string>
        },

        test2: function(map: Map<string, number>) {

        }
    }    
}

The argument of test2 must be Map<string, **number**> and the function test passes Map<string, **string**> to test2. The argument type does not match, but Typescript does not detect this error.

Why Typescript does not detect this error?

Typescript version: 2.9.2.

tsconfig.json:

{
  "compilerOptions": {
    "module": "es2017",
    "target": "es2017",
    "lib": [
      "dom",
      "es2017"
    ],
    "noImplicitAny": false,
    "sourceMap": true,
    "moduleResolution": "node"
  },
  "include": [
    :
  ],
  "exclude":  [
    :
  ]
}
6
  • 1
    Try turning on the noImplicitThis compiler option in tsconfig. I believe without that (Can't explain why - probably a bug) this is being implicitly typed as any when using the factory function syntax Commented Oct 22, 2018 at 0:49
  • Thanks for comment. Setting noImplicitThis to true could detect the error. Could you make an answer? I will accept it. Commented Oct 22, 2018 at 1:39
  • If you set that flag, does the type of this change? (Do you still get an error even if you use the method correctly?) Commented Oct 22, 2018 at 2:04
  • After setting noImplicitThis, the above code generates the error TS2345: Argument of type 'Map<string, string>' is not assignable to parameter of type 'Map<string, number>'.   Type 'string' is not assignable to type 'number'.. It looks the type of this is testIF. Commented Oct 22, 2018 at 2:49
  • That's cool! I didn't know that noImplicitThis causes the compiler to interpret this as the object's type. I thought it just caused the compiler to error out if this was interpreted as any. Commented Oct 22, 2018 at 16:35

2 Answers 2

2

The way you invoke the method can change the value of this, so TypeScript sets this to be of type any by default, which turns off type checking. You can tell TypeScript the context by creating a fake parameter called a this parameter:

function f(): testIF {

    return {
        test: function (this: testIF /* fake "this" parameter */) {
            let map: Map<string, string> = new Map();
            this.test2(map); // Error
        },

        test2: function(map: Map<string, number>) {

        }
    }    
}
Sign up to request clarification or add additional context in comments.

Comments

1

As @PSL advice, I have set noImplicitThis to true on tsconfig.json. Now Typescript can detect the error.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.