In the latest Typescript (v5.0.4 as for today) when I compile declarations for the following code:
type SomeType<T> = {
field: T;
};
const getInstance = <T>(
value: T
): SomeType<{
[K in keyof T]: T[K];
}> => {
return {
field: value,
};
};
export const variable = getInstance({
/**
* want to have it in d.ts
*/
nested: "nested",
});
I'm getting this in my d.ts
:
type SomeType<T> = {
field: T;
};
export declare const variable: SomeType<{
nested: string;
}>;
export {};
Which reflects what we have in the code, but unfortunately there is no comment. I happens specifically when I use mapped types in the returned type.
It would have been work fine If I don't use mapped type, but unfortunately I can't get rid of it in my case.
The question is how to preserve the comment in the d.ts file with mapped type? Nice stuff is that I see my comment in VSCode when I hover over variable.field.nested
property which means that Typescript preserves it somewhere but just doesn't add it to d.ts file on declaration generation stage.
I can't find authoritative documentation for exactly how the compiler chooses to preserve or discard comments in declaration files, but since you said it works fine if you just wrote SomeType<T>
instead of SomeType<{[K in keyof T]: T[K]}>
, that suggests comments might be preserved when using a generic type directly like XXX<T>
. So what if we defined an XXX
that behaves how you want?
// .ts file
type GetInstance<T> =
SomeType<{ [K in keyof T]: T[K] }>;
const getInstance = <T,>(value: T
): GetInstance<T> => {
return {
field: value,
};
};
export const variable = getInstance({
/**
* want to have it in d.ts
*/
nested: "nested",
});
This is equivalent to your code. And when we check the generated declaration file, the comment is indeed preserved!
// .d.ts file
export declare const variable: GetInstance<{
/**
* want to have it in d.ts
*/
nested: string;
}>;
export {};
If anyone finds where such behavior is documented I'd be happy to add it here.