Repository: TypeScript
Issue: Incomplete infer for generic types
Labels: Bug

<!-- 🚨 STOP 🚨 𝗦𝗧𝗢𝗣 🚨 𝑺𝑻𝑶𝑷 🚨

Half of all issues filed here are duplicates, answered in the FAQ, or not appropriate for the bug tracker. Even if you think you've found a *bug*, please read the FAQ first, especially the Common "Bugs" That Aren't Bugs section!

Please help us by doing the following steps before logging an issue:
  * Search: https://github.com/Microsoft/TypeScript/search?type=Issues
  * Read the FAQ: https://github.com/Microsoft/TypeScript/wiki/FAQ

Please fill in the *entire* template below.
-->

**TypeScript Version:**  4.0.5

<!-- Search terms you tried before logging this (so others can find this issue more easily) -->
**Search Terms:**
typescript, infer, incomplete, unknown, generic

**Expected behavior:**
The compiler should be able to extract information of the generic `Item` type from the function definition and infer `string`.

**Actual behavior:**
The compiler is able to infer the `Names` type as `{ id: string }` but the `Item` type is `unknown`.

<!-- Did you find other bugs that looked similar? -->
**Related Issues:**

**Code**
```ts
interface LoaderConfig<Key, Item> {
  loadItems: (keys: readonly Key[]) => Promise<readonly Item[]>;
  getKey: (item: Item) => Key;
  makeCacheKey: (key: Key) => string;
}

type LoaderConfigByName<Names, Item> = {
  [name in keyof Names]: LoaderConfig<Names[name], Item>;
};

function makeLoader<Names, Item>(
  configs: LoaderConfigByName<Names, Item>
): void {
  console.log(configs);
}

makeLoader({
  id: {
    loadItems: async (keys: readonly string[]): Promise<readonly string[]> => {
      return await Promise.resolve(keys);
    },
    getKey: (item: string): string => item,
    makeCacheKey: (key: string): string => {
      return key;
    }
  }
});
```



<details><summary><b>Output</b></summary>

```ts
"use strict";
function makeLoader(configs) {
    console.log(configs);
}
makeLoader({
    id: {
        loadItems: async (keys) => {
            return await Promise.resolve(keys);
        },
        getKey: (item) => item,
        makeCacheKey: (key) => {
            return key;
        }
    }
});

```


</details>


<details><summary><b>Compiler Options</b></summary>

```json
{
  "compilerOptions": {
    "noImplicitAny": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "strictPropertyInitialization": true,
    "strictBindCallApply": true,
    "noImplicitThis": true,
    "noImplicitReturns": true,
    "alwaysStrict": true,
    "esModuleInterop": true,
    "declaration": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "moduleResolution": 2,
    "target": "ES2017",
    "jsx": "React",
    "module": "ESNext"
  }
}
```


</details>

**Playground Link:** [Provided](https://www.typescriptlang.org/play?#code/JYOwLgpgTgZghgYwgAgDIHs4BNoGF0gzADmAPANIQCeANMgJKQC2AfMgN4BQyyANplkYQmAZwBcyABQBrauORQI2AryrJKVANoBdAJTIAvGwAKUdE2AiIpRcpCqGzHSwDc3ZMQhgNEycGYSQkz6RurUbjxMcLK4iAAWED5SslQSGiFsImBQoMRuAL6cnGBUAA4oGNh4BETEAEJUAHJwTNbNrSJ0QWwGHO6aIC0ooMgp6DDI7RAi2hKVOFD4hCSkUyIDQ9pdzK6c+W6cMACuIAhgwATIUbLz0KtDnY7CLJLuCDUk8reLH-VNQ-cOttnpxdBIAG7oYBYPo8d4gEToXgQAB0-GIknhtREugKRWuEG+ki4PGhEhJPD4AiC8jgIiop2ScgktiwKjUWRyIGIOjByFM5ks1lZ7OQnNyzkMbAplIUXiOUBAyDgAHc4P5+WYLFYUYpEbxwRAZHJce4ePkaGaPF4kn4AmLsrk+eLuVLkP5hJbZQTYggEraUhIXcRnY7XaEZZTFGAFUqUhFKYVzXtcUA)