TypeScript通用接口文档/注解

vxf3dgd4  于 2023-03-24  发布在  TypeScript
关注(0)|答案(1)|浏览(123)

我有以下接口和类型:

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;

我在这个(简化的)函数中使用:

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>;
    }
}

当我使用这个函数时(见下面的例子),我希望有注解/注解来记录options接口的每个字段,如下所示:

但相反,因为它是一个通用的(我认为),我什么也得不到:

因为我正在构建一个库,所以我希望options对象中的所有属性都有注解/文档,但是使用当前的泛型设置我无法做到。
编辑1在this answer之后,我将函数的签名更新为:

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

现在,关于transform方法的文档/注解工作了,并且似乎是从GetTransformJson接口中获取的(请参阅注解末尾的(json)

然而,如果我尝试做同样的事情,但使用来自基本接口的不同属性(即decrypt),我不会得到文档/注解:

z0qdvdin

z0qdvdin1#

在这种情况下,将OGet交叉以“保留”文档注解应该是安全的:

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

此外,您可能应该将O默认为undefined
不幸的是,这将不允许您使用特定于GetTransformJson的文档注解...
Playground
经过一些实验,我发现:

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> => {

它确实保留了GetTransformJsonGetTransformNo特定的文档注解,但代价是可读性和维护性。
Playground

相关问题