Repository: TypeScript
Issue: Assigning a callable return type of a generic function directly to some generic parameter results in error
Labels: Needs Investigation

**TypeScript Version:**  above 3.3.3

**Code**

To see the actual behavior depending on a version of TS it is better to [open the code below in the playground](http://www.typescriptlang.org/play/?ssl=118&ssc=3&pln=110&pc=1#code/C4TwDgpgBAwghgGwXARgiAeAKgPigXigG8oAKYALiiwEoq4A7EAbigF9mAobgEwgGNkAJ2gAzAK4N+wAJYB7BlHGyEAQWw5SnKFH6JkaCFXhJU6DQBptUUQyrkqtAnkYhOdKK94DhYydPlFZRkEACENLR09U0NjfTNMXCsdMDghOABbAGcqImsdW3tKahpnTyZrNnd6Cs4+QTS-KVkFJRUYCOtU9Ozc-N142NhB8yT+wrJip3wXCp0qjy9OAHoAKlXtVeGs6ABGKh4ZEWkEEE8srJkAcwYZBivPAZj0TeXvBpFdBSzgJ4N0OLPTAMcQZFAQIQ4bjBNSRP4JZJQX4zJEAOmAcgAogAPMAKCAMWSIUilZbLJFQGRZR4gsEQixQADyAGl3NCVKE4dF-hBEXkdAU7BSUcB0VjcfjCTJiaTyb8qTTQeChAyWZU2ZwYTBSPz4YZERNkXhRRicXiGASiQgSVAyRSFXAoLTlarWWwaNw1hsoFt4DsoAAmA5HATAU7nS43O4PYAAC2gIiy4gQvzkokeEmagSgImA4iEt3uj25CVe718Nn8LUU-DkGTAyggJh5qhJgJ5GGdEKhmpUrestfrjebCVbNERRrRpolFqlMttcsp1MdXZVTNZHt7IU5A7rDeATZGEDHfPGQsnJvF5st0utsvty6dSvp6-Vm61OoHR6og-3h6BJ7WIaZSXmakpWjadryo+q6upw7qeusmzbNAADMwbHGGZxwBc1yFjG8Y5hASYplAaaPFcBIQjI-CVlmrS5vm+HFkeZZ1D4jR0QErS-sOR7hLgDglO2CQaOyIT9lEe58UCnK7AADPJ47WBeYpgbOEH3tBip0muarvhyXLSQeI6GHJinKTouqClQqnTtec53guD46S6r7zBqH66iWQy8SZ-GkApSkGueIFqTON7zlBS7lEoDAANYMHIADuDDwZuXrIVghHID8Az+gqPzpPc0AAJIALKMqi1CEYmya-KAkBkemAAGfn-jyoQtTFMgZBkECHHAB7holKUMKiyHIQAEnIABu1FFnG0C5b8LVat1WSxil1JLTYchICl0YUJNPpcdWbQhB0q6aN0mQ5MQyFRN+wxAp2z6Qlwp02ZMVCrqUKKuJ9WzujUbinchAAixFgDIB5IoRohwNI8NDdQADKlIMKIELUpRFpCDRUAtVg3XkWt7QtQyOGRgw-WEkichEz56DdbdGTIVcMjzfdABEWDgNAADkpnmNdgsxUlvzU3hCQM0iAtQMLR4YJIo2pTgguojzE3g6dpXabGaQ8HLkh8EIPyMMbyWG8AuNyNGZHjVA5VyJ8caMCjwAMhA81CCAcYO8lrvxdSdzo1As2oaiUdR8hpWKBayUQhHOOBDthHgobs3yEIMUoEIcjxQSOtbFlsYKoby6KL1qTI60u0IDI+dpGcpVQPGCBgHLGRwHcwC907aPiPwsZKP6eg7MunySzmnGW8hkByGA6CeJ8oiu-wA1y9LNzwwmxH1c1TPGR1CTmUp3UYo8s1pNKhg2EcPzJFslt74oV+Om1R6s2kmQQAea5rY0VHnAUQ2NpDUghgADWOj6N4nBawMDyu1EWEBQgACUD6kUICggKQUDKXU-E9IEP4T6oIwVgr2zlsoKiDkIEOABCICoURThQcppZy2kVzvTgu6IAA)

```ts
type Callable<T> = { (t: T): any; };


declare function utilA<T>(
  callable: Callable<T>,
  fn: (t: T) => any
): any

declare function utilB<T>(
  callable: Callable<T>,
  params: {
    fn: (t: T) => any
  }
): any

declare function utilC<T>(
  params: {
    callable: Callable<T>,
    fn: (t: T) => any
  }
): any

/**
 * Case 1: directly assigning a callable
 */

declare const callable: Callable<number>

utilA(
  callable,
  t => t.toExponential() // t is a number, OK
)

utilB(
  callable,
  {
    fn: t => t.toExponential() // t is a number, OK
  }
)

utilC({
  callable,
  fn: t => t.toExponential() // t is a number, OK
})

/**
 * Case 2: directly assigning the result of a function returning a callable
 */

declare function computeCallableA(): Callable<number>

utilA(
  computeCallableA(),
  t => t.toExponential() // t is a number, OK
)

utilB(
  computeCallableA(),
  {
    fn: t => t.toExponential() // t is a number, OK
  }
)

utilC({
  callable: computeCallableA(),
  fn: t => t.toExponential() // t is a number, OK
})

/**
 * Case 3: directly assigning the result of a generic function returning a callable
 */

declare function computeCallableB<T>(t: T): Callable<T>

utilA(
  computeCallableB(100),
  t => t.toExponential() // t is a number, OK
)

utilB(
  computeCallableB(100),
  {
    fn: t => t.toExponential() // t is a number, OK
  }
)

utilC({
  callable: computeCallableB(100), // Error
  fn: t => t.toExponential() // t is an unknown
})

/**
 * The last case is strange IMO. The result type of `computeCallableB` is immediately known.
 * 
 * Hovering the last `utilC` shows the following:
 * 
 * function utilC<number>(params: {
 *   callable: Callable<number>;
 *   fn: (t: number) => any;
 * }): any
 * 
 * Despite the fact that TS infers generic `T` of `utilC`, assignment to `callable` param
 * gives: "Type 'Callable<number>' is not assignable to type 'Callable<unknown>'.".
 * 
 * It is hard to understand whats going on. More than that, everything works in TS v3.3.3.
 * In newer versions the behavior is broken.
 * 
 * This has an impact on the library I help to maintain. Such use cases are not rare and
 * people are forced to assign the result of `computeCallableB(100)` to a variable first,
 * and then to a `callable` parameter, which affects DX:
 */

const computeCallableBResult = computeCallableB(100)

utilC({
  callable: computeCallableBResult, // This works!
  fn: t => t.toExponential() // t is a number, OK
})
```

**Expected behavior:**

The invocation of

```ts
utilC({
  callable: computeCallableB(100), // Error
  fn: t => t.toExponential() // t is an unknown
})
```
 gives no errors.

**Actual behavior:**

Strange behavior in versions above 3.3.3.