Repository: TypeScript
Issue: String literals widened to string when destructuring function return
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.4.x, @next

<!-- Search terms you tried before logging this (so others can find this issue more easily) -->
**Search Terms:**

**Code**

```ts
  const func = <T extends string>(obj: { stringLiteral: T }): { stringLiteral: T } => {
    return obj;
  };
  
  const { stringLiteral } = func({ stringLiteral: 'Literal' });
  
  const Literal: 'Literal' = stringLiteral // Error: Type 'string' is not assignable to type '"Literal"' .ts(2322)
  
```

**Expected behavior:**
`stringLiteral` should have type 'Literal'

**Actual behavior:**

When destructured immediately it's type is widened to `string`, however if it is not destructured immediately it's type is preserved

```ts
const func = <T extends string>(obj: { stringLiteral: T }): { stringLiteral: T } => {
    return obj;
  };
  
  const Obj = func({ stringLiteral: 'Literal' });
  
  const { stringLiteral } = Obj
  
  const Literal2: 'Literal' = stringLiteral  // Works fine
```

From my tests I discovered this happens either when the string literal is a property on an object the function takes as an input and the function has an explicit return type or returns the input object as is.

Examples

input object, explicit return type

```ts
  const func = <T extends string>({stringLiteral }: { stringLiteral: T }): { stringLiteral: T } => {
      return { stringLiteral };
    };
    
  const { stringLiteral } = func({ stringLiteral: 'Literal' });
    
  const Literal: 'Literal' = stringLiteral  // Error
```

```ts
  const func = <T extends string>(obj: { stringLiteral: T }): { stringLiteral: T } => {
      return obj;
    };
    
  const { stringLiteral } = func({ stringLiteral: 'Literal' });
    
  const Literal: 'Literal' = stringLiteral  // Error
```

input obj, no explicit return type

```ts
  const func8 = <T extends string>({stringLiteral }: { stringLiteral: T }) => {
      return { stringLiteral };
    };
    
    const { stringLiteral } = func8({ stringLiteral: 'Literal' });

    const Literal: 'Literal' = stringLiteral  // Works
// // //  // / // / // / /// // // // // // // // // // // // // // // // // 
const func9 = <T extends string>(obj: { stringLiteral: T }) => {
  return { stringLiteral: obj.stringLiteral };
};

const { stringLiteral: stringLiteral9 } = func9({ stringLiteral: 'Literal' });

const Literal9: 'Literal' = stringLiteral9; // Works
```

input obj, no explicit return type, returns input obj as is

```ts
    const func10 = <T extends string>(obj: { stringLiteral: T }) => {
        return obj;
      };
      
    const { stringLiteral } = func10({ stringLiteral: 'Literal' });
  
    const Literal: 'Literal' = stringLiteral  // Error
```


It should be noted that all these errors scenario's can be fixed by asserting the input object as a const during function call

```ts
const func = <T extends string>(obj: { stringLiteral: T }): { stringLiteral: T } => {
    return obj;
  };
  
  const { stringLiteral } = func({ stringLiteral: 'Literal' } as const); // const assertion
  
  const Literal: 'Literal' = stringLiteral // Works!!
```