我正在尝试编写一种可以在我的很多代码中重复使用的类型,其中函数将返回以下形式的元组:
如果函数发生错误,元组将有一个 Error 对象作为第一个元素,null
作为第二个元素,而如果函数“成功”,它返回的元组将有一个 { {1}} 位于第一个位置,返回的数据位于第二个位置。
这有点类似于nodejs的回调风格,回调获取一个错误对象作为第一个参数(如果有错误),第二个参数中的数据(如果成功)。 现在我输入的方式看起来像这样:
null
所以在这个版本中,每个函数都会返回一个 type SuccessResponse<T> = [null, T];
type ErrorResponse<E = Error> = [E, null]
type Response<T, E = Error> = SuccessResponse<T> | ErrorResponse<E>;
并在泛型 T 中设置它自己的类型。我的问题是 Typescript 似乎正在以一种奇怪的方式合并这两个元组(至少对我来说) .
一个非常人为的例子:
Response
我在这里打错了吗?在我看来,Typescript 应该能够知道在 interface User {
name: string
};
async function getUser(userId: string): Response<User> {
try {
const user = await UserModel.findById(userId);
if (!user) {
return [new Error('No user found'), null];
}
return [null, user];
} catch (error) {
return [error, null];
}
}
;(async () => {
const [err, user] = await getUser('1');
if (err) {
err.message; // This works
return;
}
console.log(user.name); // TS: Object is possibly 'null'.(2531)
})();
子句之后 if
的类型应该是 user
而不是 User
。
请注意,我知道我可以为此使用类型保护,但是我会失去响应已经被解构的美感。代码看起来像这样:
User | null