我正在使用TypeScript编写React应用程序。
我已经编写了用于进行API调用的函数的包装器:
import { ROUTE_CANDIDATES, ROUTE_TWIG_PICK } from "../../../config/constants/routes";
import { pickSchema } from "../../../config/schemas/picks";
import { PickCreateBulkResponse, PickCreateUpdateResponse } from "../../../config/types";
import { postRequest, putRequest } from "../../utils/serverRequests";
interface PickJSON {
candidate: string;
picked_int_choice: string;
}
const pickListSchema = [pickSchema];
export const postPickCreate = (
body: PickJSON | PickJSON[]
): Promise<PickCreateUpdateResponse | PickCreateBulkResponse> => {
if (Array.isArray(body)) {
return postRequest(ROUTE_CANDIDATES + ROUTE_TWIG_PICK, body, pickListSchema) as Promise<
PickCreateBulkResponse
>;
} else {
return postRequest(ROUTE_CANDIDATES + ROUTE_TWIG_PICK, body, pickSchema) as Promise<
PickCreateUpdateResponse
>;
}
};
如您所见,我正在尝试动态声明正确的响应类型。意味着如果该函数与数组一起使用,则应返回Promise<PickCreateBuldResponse>
,而如果与单个对象一起使用,则应返回Promise<PickCreateUpdateResponse>
。如何让TypeScript知道返回的内容?如您在上面看到的,我尝试使用as
,但这是行不通的。
答案 0 :(得分:5)
您可以声明function overloads:
export function postPickCreate(body: PickJSON): Promise<PickCreateUpdateResponse>
export function postPickCreate(body: PickJSON[]): Promise<PickCreateBulkResponse>
export function postPickCreate(body: PickJSON | PickJSON[]):
Promise<PickCreateUpdateResponse | PickCreateBulkResponse> {
if (Array.isArray(body)) {
return postRequest(ROUTE_CANDIDATES + ROUTE_TWIG_PICK, body, pickListSchema) as
Promise<PickCreateBulkResponse>;
} else {
return postRequest(ROUTE_CANDIDATES + ROUTE_TWIG_PICK, body, pickSchema) as
Promise<PickCreateUpdateResponse>;
}
}
但是,由于在您的情况下,您已经在设计时知道了值的类型,而TypeScript会为您进行类型检查,所以最好的方法可能是简单地分离函数。这就是您在if
块中的函数中实际执行的操作:
export function postPickCreate(body: PickJSON): Promise<PickCreateUpdateResponse> {
return postRequest(ROUTE_CANDIDATES + ROUTE_TWIG_PICK, body, pickSchema) as
Promise<PickCreateUpdateResponse>;
}
export function postPickCreateRange(body: PickJSON[]): Promise<PickCreateBulkResponse> {
return postRequest(ROUTE_CANDIDATES + ROUTE_TWIG_PICK, body, pickListSchema) as
Promise<PickCreateBulkResponse>;
}
答案 1 :(得分:0)
您可以使用overloads正确键入该函数。
interface Foo {}
interface BarMany { many: string; }
interface BarOne { one: string; }
interface BazFunc {
(foo: Foo[]): BarMany;
(foo: Foo): BarOne;
}
const baz: BazFunc = (foo) => {
if(Array.isArray(foo)) {
return { many: "flibble" };
} else {
return { one: "flibble" };
}
};
var one = baz({});
var many = baz([]);
这实际上是一个jsFiddle:https://jsfiddle.net/z4vo5u5d/22392/
输出:
one - One: flibble, Many: undefined
many - One: undefined, Many: flibble