Repository: TypeScript
Issue: Inference fails nondeterministic when callback gets a `typeof` in an object
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.
-->

<!-- Please try to reproduce the issue with `typescript@next`. It may have already been fixed. -->
**TypeScript Version:**  3.0.0-dev.20180609

<!-- Search terms you tried before logging this (so others can find this issue more easily) -->
**Search Terms:** 
inference object keyof typeof deterministic

**Code**

```ts
function select<TFields extends { [_ in string]: string }>(fields: (a: { $: typeof document }) => TFields): keyof TFields {
	return null!;
}

function test() {
	const y = select((a) => ({
		foo: "bar"
	}));
	y;
}
```

**Expected behavior:**
`TFields` is instantiated to `{ foo: string }`. The type of `y` is `"foo"`.

**Actual behavior:**
The type of `y` depends on the order on which you query the types. If you first hover on the `y` in `const y =` or the `y` in `y;`, you get `string`. However, if you first hover `select`, then one of the following happens (not deterministic!):

- The signature of `select` is instantiated as
```ts
function select<{
    [x: string]: string;
}>(fields: (a: {
    $: Document;
}) => {
    [x: string]: string;
}): string
```
The type of `y` is `string`.
- The signature of `select` is instantiated as
```ts
select<{
    foo: string;
}>(fields: (a: {
    $: Document;
}) => {
    foo: string;
}): "foo"
```

The last case is correct. If you end up in the first case, and hover on `select` for a second time, the signature will be shown as in the second case.

The previous lines describe the behavior of VS Code. If I try it in the online playground, I always get the first case. Hovering again does not change the results, like it does in VS Code.

The problem is really specific to having a `typeof` inside an object. The inference is correct when making one of the following changes:

- Unboxing the `typeof` field, e.g. changing `a: { $: typeof document }` to `a: typeof document`
- Removing the argument from the call (`const y = select(() => ({ ...`)
- Removing the `typeof` type, e.g. changing `typeof document` to `string`

**Playground Link:** <!-- A link to a TypeScript Playground "Share" link which demonstrates this behavior --> 
http://www.typescriptlang.org/play/#src=function%20select%3CTFields%20extends%20%7B%20%5B_%20in%20string%5D%3A%20string%20%7D%3E(fields%3A%20(a%3A%20%7B%20%24%3A%20typeof%20document%20%7D)%20%3D%3E%20TFields)%3A%20keyof%20TFields%20%7B%0A%09return%20null!%3B%0A%7D%0A%0Afunction%20test()%20%7B%0A%09const%20y%20%3D%20select((a)%20%3D%3E%20(%7B%0A%09%09foo%3A%20%22bar%22%0A%09%7D))%3B%0A%09y%3B%0A%7D%0A

**Related Issues:** <!-- Did you find other bugs that looked similar? -->