typescript - 打字稿中的可选泛型
问题描述
所以我有一个对strapi服务器的api调用的包装器
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;
}
},
};
我正在尝试获取它,因此 K 是可选的,因此我可以执行以下操作
await api.post<type1, type2>(url, body);
await api.post<type1>(url, body);
我试过了
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;
}
},
};
但是我会得到输入错误,因为当返回类型应该只是 type2 时它会丢失 type1 中的一个字段,或者我会得到返回对象可能未定义。
我想知道是否有可能拥有它,所以如果两种类型都用于 post 函数,它将使用第二种类型作为返回类型还是使用第一种类型作为返回类型?
可以粘贴到打字稿游乐场的完整示例,其中包含发生错误的注释
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;
}
},
};
function postData<K, T>(url: string, data: K, jwt: string = '', failOnNotOk: boolean = true): T {
const request: T = (data) as any;
return request;
}
type user = {
email: string;
password: string;
}
type res = {
valid: string;
}
(async () => {
const url: string = 'https://google.com';
const body: user = {
email: 'test@example.com',
password: 'test1234',
};
// this gives an error about result having the possibility of being undefined
const result = await api.post<user>(url, body);
console.log(result.email);
// returns an errror about valid not being a field on user when the return type should only be res
const res = await api.post<user, res>(url, body);
console.log(res.valid);
})();
解决方案
使用给出的示例,我可能会更改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
请注意,需要显式指定而不是让编译器从 的类型推断它有点烦人body
,但如果你不介意这样做,那很好。TypeScript 缺乏对部分类型参数推断的直接支持,因此T
如果您还想U
显式指定,则无法让编译器正确推断,而且我所知道的解决方法不一定比手动指定更好T
。
无论如何,希望有所帮助;祝你好运!
推荐阅读
- python - How to solve the error when importing matplotlib in Anaconda on macOS?
- qt - Group users in Firebase RTDB
- python-3.x - pip install bad解释器:没有这样的文件或目录
- highcharts - How to use Sankey chart from highchart in Angular5
- vim - Get a parsable string with carriage returns
- jqgrid - 如何在免费 jqgrid 4.15.4 中根据特定条件执行工具栏搜索
- android - 将进度条与处理程序同步
- python - How to remove newline from end and beginning of every list element [python]
- android - Touble writing firebase write rule for pushing data
- ruby-on-rails - Heroku 应用程序删除