Lui*_*ipe 2 type-inference typescript
我想实现tryInline,它应该尝试调用一个函数并根据调用的成功或失败返回两种对象。
如果fn参数被成功调用,tryInline应该返回:
{
ok: true,
data: <The value returned by `fn`>,
error: null
}
Run Code Online (Sandbox Code Playgroud)
如果fn抛出错误,tryInline应该返回:
{
ok: false,
data: null,
error: Error
}
Run Code Online (Sandbox Code Playgroud)
我设法做到了以下几点:
type Result<D> =
| { ok: true; data: D; error: null }
| { ok: false; data: null; error: Error };
function tryInline<Fn extends (...args: any[]) => any>(
fn: Fn,
...args: Parameters<Fn>
): Result<ReturnType<Fn>> {
try {
const data = fn(...args);
return { ok: true, data, error: null };
} catch (error) {
return { ok: false, data: null, error: error };
}
}
const { ok, data, error } = tryInline((a: number, b: number) => a + b, 1, 3);
if (ok) {
console.log(ok); // inferred type: `true`
console.log(data); // inferred type: `number | null` Should be `number`
console.log(error); // inferred type: `Error | null` Should be `null`
}
if (!ok) {
console.log(ok); // inferred type: `boolean` Should be `false`
console.log(data); // inferred type: `number | null` Should be `null`
console.log(error); // inferred type: `Error | null` Should be `Error`
}
Run Code Online (Sandbox Code Playgroud)
但是,我希望能够正确推断if块内的类型,这不是当前的情况。
有没有办法解决这个推理问题?
您需要在条件分支后使用解构,因为 TS 将类型链接到对象,而不是普通变量。当你解构它们时,ok和之间的联系data就会丢失。此外,我认为这更干净,因为您正在解构您真正需要的东西。
const result = tryInline((a: number, b: number) => a + b, 1, 3);
if (result.ok) {
const { data } = result;
console.log(data); // inferred type: `number`
}
if (!result.ok) {
const { error } = result;
console.log(error); // inferred type: `Error`
}
Run Code Online (Sandbox Code Playgroud)
如果您只想在不进行分支的情况下进行解构,那么对我来说只做const { data, error } = tryInline(...)并继续进行似乎更合乎逻辑if (data) { ... }
| 归档时间: |
|
| 查看次数: |
42 次 |
| 最近记录: |