Repository: TypeScript
Issue: docs: clarify declaration merging behavior
Labels: Docs

## Search Terms

<!-- List of keywords you searched for before creating this issue. Write them down here so that others can find this suggestion more easily -->

declaration merging imported interface module declaration merging

related issue #11406

## Suggestion

*[This is a docs improvement request](https://www.typescriptlang.org/docs/handbook/declaration-merging.html)*

As I found via some helpful feedback on Gitter, in response to this [S.O. issue](https://stackoverflow.com/questions/57848134/trouble-updating-an-interface-using-declaration-merging), in order for declaration merging to work across multiple files, all subsequent declarations (after the first) need to specify the *original file* that the declared interface was created in.

For example, given a module `@rschedule/core` with the following files

```ts
// @rschedule/core/es2015/packages/core/core/date-adapter

export interface DateAdapterType {
  base: DateAdapterBase;
}
```

```ts
// @rschedule/core/index.ts

export * from './es2015/packages/core/core/date-adapter'
```

this *does not work work* (though I think it is reasonable to expect that it would):

```ts
// file_a.ts

declare module '@rschedule/core' {
  interface DateAdapterType {
    one: string;
  }
}
```

```ts
// file_b.ts

import { DateAdapterType } from '@rschedule/core';
import './file_a';

function test(date: DateAdapterType) {
  date.base; // should be type `DateAdapterBase` but instead errors that `.base` doesn't exist
  date.one; // is type `string`
}
```

This fails because `@rschedule/core` is re-exporting the `DateAdapterType` interface. The following works 

```ts
// file_a.ts

declare module '@rschedule/core/es2015/packages/core/core/date-adapter' {
  interface DateAdapterType {
    one: string;
  }
}
```

```ts
// file_b.ts

import { DateAdapterType } from '@rschedule/core';
import './file_a';

function test(date: DateAdapterType) {
  date.base; // is type `DateAdapterBase`
  date.one; // is type `string`
}
```

This existing API for declaration merging is problematic because the *true* location of the `DateAdapterType` interface within `@rschedule/core` is private to the module and could theoretically change between releases. Longer term, I'd like to see this implementation issue within typescript fixed (#33327), but in the immediate term a docs update could save future folks some pain.

I'll note that I was only able to eventually figure out what was going on via #11406 from 2016. As @MoonStorm sagely put it in a comment at that time to clarify this documentation.

> Could you please update the docs with this example, in the module augmentation section as well as in what's new ? Nobody is going to augment rxjs's Observable straight in the external module's own folder.

## Use Cases

Developer understanding and happiness

## Examples

## Checklist

My suggestion meets these guidelines:

* [x] This wouldn't be a breaking change in existing TypeScript/JavaScript code
* [x] This wouldn't change the runtime behavior of existing JavaScript code
* [x] This could be implemented without emitting different JS based on the types of the expressions
* [x] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
* [x] This feature would agree with the rest of [TypeScript's Design Goals](https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals).