Repository: TypeScript
Issue: Utility type to reference JSDoc of another type
Labels: Suggestion,Awaiting More Feedback


## Search Terms

type level jsdoc
computed jsdoc
reference jsdoc from other type

## Suggestion

Add a utility type `Docs<T>`, which, given `type T = U & Docs<V>`, results in a type `T` with the type of `U`, but with the JSDoc annotations of `V` (overriding any `U` might have). This should also add `V`'s go to definition results to `T`'s (maybe prioritized?).

This could either be implemented as a magic type like `ThisType` (e.g. `type Docs<T> = unknown` in `lib.d.ts`), or as an `intrinsic` type, as introduced in #40580.

## Use Cases

This is useful to preserve context when manipulating types (see example below).

## Examples

```typescript
interface Person {
    id: string;
    /**
     * The date this person was born
     */
    birthDate: Date;
    /**
     * The date this person died; `null` indicates that the person is still alive.
     */
    deathDate: Date | null;
    /**
     * This person's age in milliseconds. Calculated as `deathDate - birthDate`
     * when dead (`deathDate === null`), `currentDate - birthDate` when not.
     */
    age: number;
    name: string;
}

const alice: Person = {
    id: "12345",
    birthDate: new Date(),
    deathDate: null,
    age: 0,
    name: "Alice"
};

alice.deathDate // Hover `deathDate`; we can clearly see what this field means and why it might be null

type Lazy<T> = {
    [K in keyof T & string as `get${Capitalize<K>}`]: () => Promise<T[K]>
    // Proposed syntax:
    // [K in keyof T & string as `get${Capitalize<K>}`]: (() => Promise<T[K]>) & Docs<T[K]>
}

type LazyPerson = Lazy<Person>;

declare const getLazyPerson: (id: string) => LazyPerson;

const bob = getLazyPerson("1111");

bob.getDeathDate // Hover `getDeathDate`; we've lost all information about what this field means. Why could it be null?
```
[Playground Link](https://www.typescriptlang.org/play?ts=next#code/FASwdgLgpgTgZgQwMZQAQAVYGcD2ZUDewqJqIAJgFypYQzgDmA3MaQPQBUHrpHqAKgAs05BNFQRBILKgAO2PKgDuCGQCMcMMDxIc2OtSBiSAImKjUz0FqVSdut1HyEjzEqTPkxc+ciCjkTKgABmAArgA2EcFkYH5I5jKSYu5oXj5kMrQgUagIESAAblAAdDpO+rbkUGKCVhao9agAPqjhUTbsXOXOHnIKYADkMggMaOCoALY5BVhQSHjkWCWoAML5SJHm5HkywdW1TQC0qIbGdebBPcrCvjU7ABT7NaZuALwfbZHRAJQANCFNjAYFBIMdTkZXtAYkpbm0cBAyo49DpRg1wpM1LBOiQwAhJg1aPQwMxgABfYDABZgWh5AooaiYbyKN6EHQUagAIgAjAAmADMABYAKycv4GSEXaDUMBQJSNcwPf46A5Q9HfcW2NHUAAMmtIeIJXIAgvSoJzySxgPkQCgSqqpWg2GxUAAJHDFGAhB31YJBJRoBL4JARGowCIATxoUDQsJSkmkqDg-giOwJCBpeTiNyjIAgUxADEE+axXyilIgEfkqAAMggAF4RgA8-AAfKhWURbABtADSsVQAGsoBGcHABKgAGQ0OiMXYhMYQAAkBHWsjzNvrUCbvdbZOCAF1qEqO+30DAcNM5i2+wfWzpnRgL7IcHMdlgI5AEAAPSgPl19gOw6juO-BTjOxIMPOwSLiua4bgUW47nuh7HiebxnheV7bvwt6tj84EmDgSBYDevZ3uSFZVmgdaNkyGSsrRzb0XgrZWtUIYICCqDUrSi5MSxYDHhyEGMARGG1g2EaCVavEljgagdqg-FSYJDw8tymmcj8VoaGoJSLiYLyOnYLrup6C5QBARmHJc-pQIMxSoBEr75vkESxHAmiTGIICKAgGhhPmcb5gmMjJlAqZTDUNIrAA6oIUYLJEOx5qcaDtBEAD8wBAA)
## 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).