TypeScript:我可以使用“never”来消除标记联合的分支吗?
TypeScript: Can I use `never` to eliminate branches of a tagged union?
我有一个名为 Result
的通用实用程序类型,用于可能 return 一个值或可能 return 一个错误的操作:
export type Result<T, E> =
| {ok: true, value: T}
| {ok: false, err: E};
// Normal use
const r: Result<number, string> = performOperation1();
if (!r.ok) {
reportError(r.err);
return;
}
doSomething(r.values);
如果我为 E
类型参数传入 never
,我知道 ok
必须是 true
,但 TypeScript 不会:
const r: Result<number, number> = performOperation2();
doSomething(r.value);
有没有办法让 TypeScript 理解这里传入 never
可以消除错误分支?
注意:在这个小例子中,performOperation2
可以 return number
而不是 Result
。但是在我的完整代码库中,所有这些“操作”功能都符合一个接口,returns Result
.
如果你可以改变 Result
你可以添加一个条件类型,如果传入 never
则不添加 false 分支:
export type Result<T, E> =
| {ok: true, value: T}
| ([E] extends [never] ? never : {ok: false, err: E} )
declare const r2: Result<number, never>
doSomething(r2.value);
您还可以使用 Exclude
从联合中排除 false
分支:
declare const r2: Exclude<Result<number, never>, { ok: false}>
doSomething(r2.value);
这不是对您问题的直接回应,但如果您无法更改,这可能是一个选项 Result
我有一个名为 Result
的通用实用程序类型,用于可能 return 一个值或可能 return 一个错误的操作:
export type Result<T, E> =
| {ok: true, value: T}
| {ok: false, err: E};
// Normal use
const r: Result<number, string> = performOperation1();
if (!r.ok) {
reportError(r.err);
return;
}
doSomething(r.values);
如果我为 E
类型参数传入 never
,我知道 ok
必须是 true
,但 TypeScript 不会:
const r: Result<number, number> = performOperation2();
doSomething(r.value);
有没有办法让 TypeScript 理解这里传入 never
可以消除错误分支?
注意:在这个小例子中,performOperation2
可以 return number
而不是 Result
。但是在我的完整代码库中,所有这些“操作”功能都符合一个接口,returns Result
.
如果你可以改变 Result
你可以添加一个条件类型,如果传入 never
则不添加 false 分支:
export type Result<T, E> =
| {ok: true, value: T}
| ([E] extends [never] ? never : {ok: false, err: E} )
declare const r2: Result<number, never>
doSomething(r2.value);
您还可以使用 Exclude
从联合中排除 false
分支:
declare const r2: Exclude<Result<number, never>, { ok: false}>
doSomething(r2.value);
这不是对您问题的直接回应,但如果您无法更改,这可能是一个选项 Result