我希望使用实用工具“条件类型”来改进API响应中的自定义类型,以便如果响应成功,响应将匹配“成功”类型。否则,响应应该与"Error“类型匹配。
interface User {
id: number;
name: string;
}
interface Fruits {
id: number;
color: string;
}
type Data = [] | User[] | Fruits[];
type ApiResponse<T> = T extends Data ? { data: T; message: string } : undefined;
interface Success<T extends Data> {
status: "loaded";
data: T;
}
interface Error {
status: "error";
data: null;
}
type Status<T> = T extends Data ? Success<T> : Error;
type LoadDataObj<T> = {
successful: boolean;
message: string;
} & Status<T>;
function setResponse<T extends Data | undefined>(
response?: ApiResponse<T>
): LoadDataObj<T> {
return {
successful: !!response,
message: response?.message ?? "",
data: response?.data ?? null,
status: response ? "loaded" : "error"
}
as LoadDataObj<T>;
// as unknown as LoadDataObj<T>; // if i remove this comment it works
}
const response = setResponse({ data: [{ id: 1, name: "bob" }], message: "data received" });
const responseEmpty = setResponse({ data: [], message: "data is empty" });
const responseError = setResponse();
console.log("response", response);
console.log("responseEmpty", responseEmpty);
console.log("responseError", responseError);目前,我在函数体中得到了这个错误消息:
Conversion of type '{ successful: boolean; message: string; data: User[] | Fruits[] | null; status: "loaded" | "error"; }' to type 'LoadDataObj<T>' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
Type '{ successful: boolean; message: string; data: User[] | Fruits[] | null; status: "loaded" | "error"; }' is not comparable to type 'Status<T>'.ts(2352)发布于 2022-06-22 11:42:18
interface User {
id: number;
name: string;
}
interface Fruits {
id: number;
color: string;
}
type ApiData = User[] | Fruits[];
type ApiResponse<T extends ApiData> = { data: T; message: string }
interface Success<T extends ApiData> {
successful: true
status: "loaded";
data: T;
}
interface Error {
successful: false
status: "error";
data: undefined;
}
type LoadDataObj<T extends ApiData> = (Success<T> | Error) & {
message: string
}
export const setResponse = <T extends ApiData>(
response?: ApiResponse<T>
): LoadDataObj<T> => {
return {
successful: !!response,
message: response?.message ?? 'some error message',
data: response?.data ?? undefined,
status: response ? 'loaded' : 'error'
} as LoadDataObj<T>
};
const response = setResponse({ data: [{ id: 1, name: "bob" }], message: "OK" });
if (response.successful) {
/*
const success: SuccessResponse<{
id: number;
name: string;
}[]> & {
message: string;
}
*/
const success = response
} else {
/*
const error: ErrorResponse & {
message: string;
}
*/
const error = response
}https://stackoverflow.com/questions/72710350
复制相似问题