假设我有一个基于下面定义的类型的对象ApiErrorType | ApiSuccessType
,这两个类型有一些相似之处,但是timestamp
只与ApiErrorType
相关,如果isError
是false
,则timestamp
永远不会出现。
我想通过一个返回MyErrorType | MySuccessType
的格式化函数将这个对象与union类型放在一起。重要的是,下游代码可以根据isError
的值知道它正在处理这两种类型中的一种。
我能想到的唯一方法是让我的格式化函数有两个单独的返回语句,并创建局部变量以避免应用于两个返回的冗余代码。
有没有更优雅的方法来实现这个功能?更类似于betterFormatter
函数,但实际上它并不起作用?
interface Base {
readonly isError: boolean;
readonly timestamp?: number;
readonly msg: string;
}
interface ApiErrorType extends Base {
readonly isError: true
readonly timestamp: number;
}
interface ApiSuccessType extends Base {
readonly isError: false;
readonly timestamp: undefined;
}
const errorObj = {
isError: true,
timestamp: 787149920,
msg: "errored"
} as const;
const successObj = {
isError: false,
timestamp: undefined,
msg: "succeeded"
} as const;
interface MyErrorType {
readonly isError: true;
readonly date: Date;
readonly msg: string;
}
interface MySuccessType {
readonly isError: false;
readonly date: undefined;
readonly msg: string;
}
const formatter = (obj: ApiErrorType | ApiSuccessType): MyErrorType | MySuccessType => {
// This version works, but it requires two separate returns, and requires `msg` to be
// assigned to a local variable to be reused in both places. Overall, it's repetative.
const msg = obj.msg.toUpperCase();
if (obj.isError) {
return {
isError: obj.isError,
date: new Date(obj.timestamp),
msg
}
}
return {
isError: obj.isError,
date: undefined,
msg
};
};
// TODO: How could I accomplish this?
const betterFormatter (obj: ApiErrorType | ApiSuccessType): MyErrorType | MySuccessType => {
// This version should have one return, like the below, but I should somehow be able to
// tell TypeScript that the return type is in face `MyErrorType | MySuccessType`.
// As written, `betterFormatter` does not work.
return {
isError: obj.isError,
date: obj.timestamp ? new Date(obj.timestamp) : undefined,
msg: obj.msg.toUpperCase()
};
}
const error = formatter(errorObj);
const success = formatter(successObj);
if (error.isError) {
// We know this is a date
error.date.getDate();
}
if (!success.isError) {
// We know this is undefined
console.log(success.date === undefined);
}
2条答案
按热度按时间zsohkypk1#
这里有一种方法可以用单个返回值来实现这一点,但我认为它的可读性较低。
k3bvogb12#
您可以使用区分联合类型来更好地定义您的API响应:
如果你想玩它:
typescript Playground链接