打字稿中的可选泛型
Optional Generics in typescript
所以我有一个 api 调用 strapi 服务器的包装器
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;
}
},
};
但是我会得到输入错误,因为当 return 类型应该只是 type2 时它会缺少 type1 中的一个字段,或者我会得到 return 对象可能未定义。
我想知道是否可以使用它,所以如果两种类型都用于 post 函数,它将使用第二种类型作为 return 类型或使用第一种类型作为return 类型?
可以粘贴到 typescript playground 的完整示例,并在出现错误的地方添加注释
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
的类似键的属性)。这里 return 类型将只是 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 缺乏对 partial type parameter inference, so there's no way to just have the compiler infer T
properly if you'd also like to specify U
explicitly, and 的直接支持并不一定比您自己手动指定 T
更好。
总之,希望对您有所帮助;祝你好运!
所以我有一个 api 调用 strapi 服务器的包装器
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;
}
},
};
但是我会得到输入错误,因为当 return 类型应该只是 type2 时它会缺少 type1 中的一个字段,或者我会得到 return 对象可能未定义。
我想知道是否可以使用它,所以如果两种类型都用于 post 函数,它将使用第二种类型作为 return 类型或使用第一种类型作为return 类型?
可以粘贴到 typescript playground 的完整示例,并在出现错误的地方添加注释
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
的类似键的属性)。这里 return 类型将只是 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 缺乏对 partial type parameter inference, so there's no way to just have the compiler infer T
properly if you'd also like to specify U
explicitly, and T
更好。
总之,希望对您有所帮助;祝你好运!