Home > Back-end >  How to do TypeScript tsdoc documentation for function argument with generic type that extends an int
How to do TypeScript tsdoc documentation for function argument with generic type that extends an int

Time:10-18

Consider the following code, note the documentation of someField:

interface Test {
    /**
     * Some description.
     * lorum ipsum.
     * foo bar.
     */
    someField: string;
}

function withGeneric<T extends Test>(arg: T) {
    return arg;
}

function withoutGeneric(arg: Test) {
    return arg;
}

withGeneric({
    someField: ""
});

withoutGeneric({
    someField: ""
});

When I hover with my mouse over someField in the withoutGeneric call, VSCode nicely shows me the documentation:

enter image description here

However, when hovering over someField in the withGeneric call, the documentation is not shown:

enter image description here

Is there a way to make the tsdoc documentation work with the generic argument too?

CodePudding user response:

Consider that when you create the inline object, it is not typed as Test:

const config = {
    someField: ""
};

Your withoutGeneric function, by definition, takes a Test-typed argument, so TypeScript can infer the property types. However, when your function is generic but you don't explicitly set the generic type then TypeScript will infer the generic type from the inline object's type, which is just the default inferred type you can see above.

You can see this in the intellisense:

TypeScript is inferring the generic type as { someField: string; }. This satisfies the requirements of the Test interface, but the value is its own inferred default type, not Test.

Consider the following example:

interface Foobar {
    /**
     * Unrelated doc string
     */
    someField: string;
}

const config:Foobar = {
    someField: ""
}

You get the following intellisense:

Note that the withGeneric function is satisfied by the Foobar type because it has the required properties and they are of the correct type. However, the doc string associated with someField would be Unrelated doc string because that is the type of the config variable.

If you explicitly set the generic type of your function, then it will behave as you expected.

withGeneric<Test>({
    someField: ""
});

Yields the following:

If you explicitly set the type to Foobar, then you'll get Foobar's doc strings:

withGeneric<Foobar>({
    someField: ""
});

yields:

CodePudding user response:

I found an answer that works for my purpose. Add a union with the extended from type:

/**
 * withGeneric sample
 * @typeParam T - must be a Test
 * @param arg 
 * @returns 
 */
function withGeneric<T extends Test>(arg: T & Test) {
    return arg;
}

Now VSCode does show the documentation:

enter image description here

It feels like a trick, but I fail to see any disadvantages to it?

  • Related