Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

TypeScript generic interface documentation/comments

I have the following interfaces and types:

type TransformOptions = 'auto' | 'binary' | 'json';

interface Get {
    /**
     * How long to keep the value in cache
     */
    maxAge?: number
    /**
     * Whether to decrypt the param or not
     */
    decrypt?: boolean
    /**
     * Whether to transform the param or not
     */
    transform?: TransformOptions
}

interface GetTransformJson extends Get {
    /**
     * Whether to transform the param or not (json)
     */
    transform?: 'json'
}

interface GetTransformNo extends Get {
    transform?: never
}

type GetOptions = GetTransformNo | GetTransformJson | undefined;

type RetType<O = undefined> =
    undefined extends O ? string :
    O extends GetTransformNo ? string :
    O extends GetTransformJson ? Record<string, any> :
    never;

Which I use in this (simplified) function:

declare function apiCall(name: string): Promise<string>;


const getParameters = async <O extends GetOptions | undefined>(name: string, options?: O): Promise<RetType<O> | undefined> => {
    const value = await apiCall(name);

    if (options?.transform === 'json') {
        const parsed = JSON.parse(value);

        return parsed as RetType<O>;
    } else {
        return value as RetType<O>;
    }
}

When I use this function (see example below), I would like to have annotations/comments that document each one of the fields of the options interface like below:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

enter image description here

but instead, since it’s a generic (I think), I get nothing:
enter image description here

Since I’m building a library, I would like to have comments/documentation for all the properties in the options object, but using the current generics setup I am not able to.


EDIT 1
Following this answer, I have updated the signature of the function to this:

const getParameters = async <O extends GetOptions | undefined = undefined>(
    name: string,
    options?: O & GetOptions
): Promise<RetType<O> | undefined> => {

Now the docs/comment on the transform method work and seem to get picked up from the GetTransformJson interface (see (json) at the end of the comment:
enter image description here

However if I try to do the same but with a different attribute that comes from the base interface (i.e. decrypt) I don’t get the docs/comments:

enter image description here

>Solution :

In this case, it should be safe to intersect O with Get to "carry over" doc comments:

const getParameters = async <O extends GetOptions | undefined = undefined>(
    name: string,
    options?: O & Get
): Promise<RetType<O> | undefined> => {

Also, you should probably default to undefined for O.

Unfortunately, this won’t allow you to use the doc comment specific to GetTransformJson

Playground


After some experimentation, I found this:

const getParameters = async <O extends GetOptions | undefined = undefined>(
    name: string,
    options?: O & (O extends GetTransformNo ? GetTransformNo : O extends GetTransformJson ? GetTransformJson : Get)
): Promise<RetType<O> | undefined> => {

which does preserve doc comments specific to GetTransformJson and GetTransformNo, but at the cost of readability and maintenance.

Playground

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading