Microsoft/TypeScript

Type variable not inferred correctly unless unused declaration is provided

Open

#52,432 opened on Jan 26, 2023

View on GitHub
 (1 comment) (0 reactions) (0 assignees)TypeScript (48,455 stars) (6,726 forks)batch import
BugDomain: check: Type InferenceHelp Wanted

Description

Bug Report

The described bug was noticed during debugging of the declarations provided with the Vue framework.

🔎 Search Terms

generic, inference, function, overload

🕗 Version & Regression Information

All 4.x versions available on the playground.

⏯ Playground Link

Playground link with relevant code

💻 Code

interface Methods {
  [key: string]: Function;
}

interface Param<M extends Methods> {
  data: (this: M) => any;
  methods: M;
}

declare function fun<M extends Methods = {}>(
  param: Param<M> & ThisType<M>
): void;

// Uncommenting the declaration below results in proper type inference of M

// declare function fun<M extends Methods = {}>(
//   param: { unusedProperty: true } & Param<M> & ThisType<M>
// ): void;

fun({
  data() {
    this.myMethod(); // Even after uncommenting the overloaded version, context is not properly inferred here
  },
  methods: {
    myMethod() {},
    mySecondMethod() {
      this.myMethod(); // Error without uncommenting the declaration
    }
  },
});

🙁 Actual behavior

  1. Proper inference of the M type variable and this context in the methods section depends on having an unused overloaded version of a function.
  2. Even though M is properly inferred for fun (visible after hovering over the function) and this context in methods after uncommenting the unused declaration, this context in data is still not properly inferred (when hovering over this, it looks as it is inferred to the default {}).

🙂 Expected behavior

M type variable is properly inferred in both data function and methods section without redundant declarations.

Contributor guide