Repository: angular
Issue: Why is Route#data a type instead of an interface?
Labels: feature,freq4: critical,area: router,state: confirmed,cross-cutting: types,P4,feature: under consideration,feature: votes required

<!--🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅

Oh hi there! 😄

To expedite issue processing please search open and closed issues before submitting a new one.
Existing issues often contain information about workarounds, resolution, or progress updates.

🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅-->


# 🐞 bug report

### Affected Package
<!-- Can you pin-point one or more @angular/* packages as the source of the bug? -->
<!-- ✍️edit: --> The issue is caused by package @angular/router

### Description

<!-- ✍️--> A clear and concise description of the problem...
When we work on the routing configuration, sometimes we leverage the `Route#data` property to add metadata for a specific route. Eg: `permissions` information like the following:

![image](https://user-images.githubusercontent.com/25516557/87783836-dfe06d00-c7fa-11ea-8260-5ee2821fd302.png)

In my use-case, I'd like to type `Route#data` to have an optional property `requiredPermission` which is a Tuple of `[PermissionNames, Privilege]`. And I want to enforce this type specifically for `requiredPermission` if it is added to a `Route#data`. Normally, I'd just go to `typings.d.ts` (or whatever `*.d.ts` you have at root) and override a library's interface there. Eg:

![image](https://user-images.githubusercontent.com/25516557/87783966-16b68300-c7fb-11ea-8311-6f23dc905944.png)

But for the case of `Route#data`, it has `type Data = {}` tied to it and `Type` does not allow for Declaration Merging so TypeScript doesn't allow me to override `Route#data` as the above screenshot shows. This prevents me from enforcing the correct typings for `requiredPermission`, hence leads to bad Developer Experience (in our cases) and Runtime bugs (instead of Compilation time). 

If `Route#data` was an interface (which allows for Declaration Merging), I could indeed achieve the following:
![image](https://user-images.githubusercontent.com/25516557/87784074-406faa00-c7fb-11ea-9b23-870dbe8502f9.png)
![image](https://user-images.githubusercontent.com/25516557/87784084-436a9a80-c7fb-11ea-92bb-3c3a849c9172.png)
![image](https://user-images.githubusercontent.com/25516557/87784090-46658b00-c7fb-11ea-8181-00448b15b41b.png)

Before writing up this issue, I was going to submit a PR right away to "fix" the bug. But looking at the source code, there are many different places (other than `Route#data`) being given types with `Type` instead of `interface`. 

- Is there a reason for using `Type` rather than `Interface` for these cases? 
- If I were to submit a PR, would I need to take into consideration of other `Type` other than `Route#data` to change those into `Interface`?

## 🔬 Minimal Reproduction
<!--
Please create and share minimal reproduction of the issue starting with this template: https://stackblitz.com/fork/angular-ivy
-->
A good way to reproduce this (as the screenshots above have shown) is to:
1. Create a new Angular app (or use existing Angular app)
2. Create a `typings.d.ts` on the same level as `main.ts` (or use existing `*.d.ts` on that same level)
3. Try to merge `Data` to have custom typed properties:

```ts
declare module '@angular/router'  {
   interface Data {
      requiredPermission?: [number, string]
   }
}
```
4. TypeScript will show error: Duplicate identifier Data

Issues that don't have enough info and can't be reproduced will be closed.

You can read more about issue submission guidelines here: https://github.com/angular/angular/blob/master/CONTRIBUTING.md#-submitting-an-issue
-->

## 🌍  Your Environment

**Angular Version:**
<pre><code>
<!-- run `ng version` and paste output below -->
<!-- ✍️-->

     _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/


Angular CLI: 9.1.8
Node: 12.13.0
OS: darwin x64

Angular:
...
Ivy Workspace:

Package                      Version
------------------------------------------------------
@angular-devkit/architect    0.901.8
@angular-devkit/core         9.1.8
@angular-devkit/schematics   9.1.8
@schematics/angular          9.1.8
@schematics/update           0.901.8
rxjs                         6.5.4
</code></pre>