Repository: TypeScript
Issue: Generics Aliasing and Partial Specialization
Labels: Suggestion,In Discussion

# Suggestion

<!--
  Please fill in each section completely. Thank you!
-->

## 🔍 Search Terms

<!--
  💡 Did you know? TypeScript has over 2,000 open suggestions!
  🔎 Please search thoroughly before logging new feature requests as most common ideas already have a proposal in progress.
  The "Common Feature Requests" section of the FAQ lists many popular requests: https://github.com/Microsoft/TypeScript/wiki/FAQ#common-feature-requests

  Replace the text below:
-->

List of keywords you searched for before creating this issue. Write them down here so that others can find this suggestion more easily and help provide feedback.
generics specialization

## ✅ Viability Checklist

<!--
   Suggestions that don't meet all these criteria are very, very unlikely to be accepted.
   We always recommend reviewing the TypeScript design goals before investing time writing
   a proposal for ideas outside the scope of the project.
-->
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, new syntax sugar for JS, etc.)
* [X] This feature would agree with the rest of [TypeScript's Design Goals](https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals).


## ⭐ Suggestion

<!-- A summary of what you'd like to see added or changed -->

Add Generics aliasing and partial Specialization

## 📃 Aliasing Example

```typescript
// In external library

export type Monoid<T> = {
  concat: (x: T, y: T) => T;
  empty: T;
};
export type MonoidFn<T> = (concat: (x: T, y: T) => T, empty: T) => Monoid<T>;

// in user code
const monoid: MonoidFn<~T> = (concat, empty) => ({ concat, empty }); // impossible today, T is undefined

```
Here we want the monoid function to still be generic and still using the original library generic definition. Using `~T` tells the compiler  we know that T is undefined, just make an alias.

## 📃 Partial Specialization Example
```typescript
// In external library

export type AggregateFn<T, U> =  (map: (item: T) => U) => (array: T[]) => U;

// in user code
const sum: AggregateFn<~T, number> = mapReduceSum<T,number>(); // impossible today, T is undefined
```

Here we want to specialize AggregateFn and make sum an AggregateFn<T, number>, that is still generic but specialized for numbers. Using `~T` tells the compiler  we know that T is undefined, so make a partial specialization.
<!--
  If you were announcing this feature in a blog post, what's a short explanation that shows
  a developer why this feature improves the language?
-->

## 💻 Use Cases

This is almost madatory for decent functional programming without having to redeclare functions of an external library.
Examples should be sufficient to explain a basic use case
<!--
  What do you want to use this for?
  What shortcomings exist with current approaches?
  What workarounds are you using in the meantime?
-->