我有以下代码,它是进行 API 调用和处理响应的简化版本。
type Result<TValue, TError> =
| { ok: true, value: TValue}
| { ok: false, msg: TError };
function sleep(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function testRequest(): Promise<{success: true, data: number} | {success: false, msg: string}> {
await sleep(1);
const roll = Math.random();
if (roll > 0.3) {
return { success: true, data: 123 };
} else if (roll > 0.6) {
return { success: false, msg: 'hello world' };
} else {
throw new Error('value to high');
}
}
async function runner(): Promise<Result<number, string>>{
return await testRequest()
.then( res => {
if (res.success) {
return { ok: true, value: res.data }
} else {
return { ok: false, msg: res.msg }
}
})
.catch( error => {
console.error('testRequest failed', { error });
return { ok: false, msg:'request failed'}
})
}
类型检查器在
return await testRequest()
行返回错误:
Type '{ ok: boolean; value: number; msg?: undefined; } | { ok: boolean; msg: string; value?: undefined; } | { status: string; msg: string; }' is not assignable to type 'Result<number, string>'.
Type '{ ok: boolean; value: number; msg?: undefined; }' is not assignable to type 'Result<number, string>'.
Type '{ ok: boolean; value: number; msg?: undefined; }' is not assignable to type '{ ok: false; msg: string; }'.
Types of property 'ok' are incompatible.
Type 'boolean' is not assignable to type 'false'.
Result
是成功和失败对象的联合,每个对象返回一个代表布尔值 status
和关联的 value
或 msg
键。
错误消息表明无法为类型
{ok: true, value: string}
返回 Result<number, string>
。然而,在testRequest
中使用相同的模式没有任何问题?
我可以修复
runner()
哪些问题才能使其适用于成功|失败类型?
一个简单的解决方案是将
Result
作为 const 返回,因为默认情况下该对象将具有 boolean 类型的属性 ok
:
.then( res => {
if (res.success) {
return { ok: true, value: res.data } as const
} else {
return { ok: false, msg: res.msg } as const
}
})
// or
.then( res => {
if (res.success) {
return { ok: true as true, value: res.data }
} else {
return { ok: false as false, msg: res.msg }
}
})