打字稿中的可选泛型

时间:2020-01-02 18:36:37

标签: typescript typescript-generics

所以我有一个包装,用于对Stradi服务器的api调用

wait

我正在尝试获取它,所以K是可选的,因此我可以进行以下操作

export const api = {
    post: async<T extends unknown, K>(url: string, body: Partial<T>, jwt?: string): Promise<K> => {
        try {
            const result = await postData<Partial<T>, K>(url, body, jwt);
            return result;
        } catch (e) {
            throw e;
        }
    },
};

我尝试过

 await api.post<type1, type2>(url, body);
 await api.post<type1>(url, body);

但是我要么会遇到输入错误,因为当返回类型仅应为type2时,它将丢失type1中的一个字段,否则我将获得返回对象可能未定义的信息。

我想知道是否可以使用这两种类型,如果将两种类型都用于post函数,它将使用第二种类型作为返回类型还是将第一种类型用作返回类型?

完整示例,可以将其粘贴到Typescript游乐场,并附上发生错误的注释

export const api = {
    post: async<T extends unknown, K = undefined>(url: string, body: Partial<T>, jwt?: string): Promise<K | T> => {
        try {
            const result = await postData<Partial<T>, K | T>(url, body, jwt);
            return result;
        } catch (e) {
            throw e;
        }
    },
};

1 个答案:

答案 0 :(得分:0)

使用给出的示例,我可能将echo $(ls)更改为:

api.post

(我将const api = { post: async<T extends unknown, U = T>( url: string, body: Partial<T>, jwt?: string ): Promise<U> => { try { const result = await postData<Partial<T>, U>(url, body, jwt); return result; } catch (e) { throw e; } }, }; 更改为K,因为名称U通常意味着可分配给K的类似键的属性)。在这里,返回类型将仅为keyof any,如果未指定,则Promise<U>将默认为U。这给出了以下行为:

T

我想你想要的。请注意,需要显式指定const result = await api.post<user>(url, body); console.log(result.email); // okay const res = await api.post<user, res>(url, body); console.log(res.valid); // okay 而不是让编译器从user的类型中推断出它有点烦人,但是如果您不介意这样做,那就很好了。 TypeScript缺乏对partial type parameter inference的直接支持,因此,如果您还想显式指定body,而the workarounds I know about不是,则无法让编译器正确地推断T。不一定比仅手动指定U更好。

无论如何,希望能有所帮助;祝你好运!

Playground link to code