TypeScript:有条件地声明函数的 return 类型
TypeScript: Conditionally declare the return type of a function
我正在使用 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
>;
}
};
如您所见,我正在尝试动态断言正确的响应类型。这意味着如果该函数与数组一起使用,它应该 return a Promise<PickCreateBuldResponse>
,而如果它与单个对象一起使用,它应该 return Promise<PickCreateUpdateResponse>
。我怎样才能让 TypeScript 知道它 return 是什么?正如您在上面看到的,我尝试使用 as
,但这不起作用。
您可以声明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>;
}
您可以使用 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
我正在使用 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
>;
}
};
如您所见,我正在尝试动态断言正确的响应类型。这意味着如果该函数与数组一起使用,它应该 return a Promise<PickCreateBuldResponse>
,而如果它与单个对象一起使用,它应该 return Promise<PickCreateUpdateResponse>
。我怎样才能让 TypeScript 知道它 return 是什么?正如您在上面看到的,我尝试使用 as
,但这不起作用。
您可以声明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>;
}
您可以使用 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