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:
However, when hovering over someField
in the withGeneric
call, the documentation is not shown:
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:
It feels like a trick, but I fail to see any disadvantages to it?