Skip to content

Verbose version of QuickInfo for Generics #34944

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
5 tasks done
jantimon opened this issue Nov 6, 2019 · 2 comments
Closed
5 tasks done

Verbose version of QuickInfo for Generics #34944

jantimon opened this issue Nov 6, 2019 · 2 comments
Labels
Duplicate An existing issue was already created

Comments

@jantimon
Copy link

jantimon commented Nov 6, 2019

Search Terms

QuickInfo
Generics

Suggestion

Most of the time types which include generics are very hard to understand.

It would be great if there would be a expand feature for QuickInfo (e.g. a + button inside the tooltip) which tries to evaluate generics.

If that it not possible it would be great if an CompilerAPI would be available to allow IDE plugin developers to create a type explorer.

Typescript

Examples

Relevant part of the example (click to enlarge):
const example1 /** 1 **/ = flatten({
    firstLetter: 'A',
    secondLetter: { value: 'B' }
})

const example1 /** 2 **/: { firstLetter: { id: string }, secondLetter: { id: string } } = example1;
Full Example
type FancyGeneric<TBase> = TBase extends string ? { id: string } : TBase extends { value: string } ? { id: string } : TBase;

type FancyGenericMap<
    TInputStructure extends { [key in keyof TInputStructure]: string | { value: string } }
    > = { [key in keyof TInputStructure]: FancyGeneric<TInputStructure[key]> };



function flatten<TInput extends { [key in keyof TInput]: string | { value: string } }>(input: TInput): FancyGenericMap<TInput> {
    const result: FancyGenericMap<TInput> = {} as FancyGenericMap<TInput>;
    (Object.keys(input) as Array<keyof typeof input>).forEach((key) => {
        const value: string | { value: string } = input[key];
        result[key] = { id: typeof value === 'string' ? value : value.value } as FancyGeneric<TInput[keyof TInput]>;
    });
    return result;
}

const example1 = flatten({
    firstLetter: 'A',
    secondLetter: { value: 'B' }
})

const example2: { firstLetter: { id: string }, secondLetter: { id: string } } = example1;

Playground

As you can see the types are the same for /** 1 **/ and /** 2 **/ but lets compare the QuickInfo:

The first QuickInfo for /** 1 **/

const example1: FancyGenericMap<{
    firstLetter: string;
    secondLetter: {
        value: string;
    };
}>

In this case you can not tell the structure of the object without reading the FancyGenericMap implementation.

Lets see in contrast the second QuickInfo for /** 2 **/:

const example2: {
    firstLetter: {
        id: string;
    };
    secondLetter: {
        id: string;
    };
}

For the second example it is way easier to understand the structure.

Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals.
@jcalz
Copy link
Contributor

jcalz commented Nov 6, 2019

Duplicate of #25784 and #28508

@RyanCavanaugh RyanCavanaugh added the Duplicate An existing issue was already created label Nov 6, 2019
@typescript-bot
Copy link
Collaborator

This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

4 participants