javascript - 基于可区分联合的缩小打字稿泛型类型
问题描述
我有一些类型定义,如下所示。
type PayloadType = 'A' | 'B';
interface Payload<T extends PayloadType> {
type: T;
}
interface PayloadA extends Payload<'A'> {
state: string
}
interface PayloadB extends Payload<'B'> {
serialNumber: string;
}
type TPayload = PayloadA | PayloadB;
type PayloadInterpretation<T extends TPayload> = {
payload: T;
entries: T[]; // This property is only for demonstration purpose
};
type TPayloadInterpretation = PayloadInterpretation<PayloadA> | PayloadInterpretation<PayloadB>;
function f(interpretation: TPayloadInterpretation) {
if (interpretation.payload.type === 'B') {
const payload = interpretation.payload; // payload is of type PayloadB
const entries = interpretation.entries; // entries is of type PayloadA[] | PayloadB[]
}
}
评论表明,即使是有效载荷的类型也可以正确地缩小到PayloadB
基于区分联合,但类型仍然T[]
是.entries
PayloadA[] | PayloadB[]
我在想如果 typescript 知道T
有效载荷的类型PayloadA
,它也应该能够缩小entries: T[]
到entries: PayloadB[]
. 我知道我可以进行类型转换,例如:
function f(interpretation: TPayloadInterpretation) {
if (interpretation.payload.type === 'B') {
const payloadBInterpretation = interpretation as PayloadInterpretation<PayloadB>;
...
}
}
但我的问题是有没有其他方法可以做到这一点?
代码在打字稿操场上。
谢谢!
解决方案
当您检查 时interpretation.payload.type
,您只是在缩小interpretation.payload
对象。你实际上并没有做任何事情来缩小interpretation.entries
.
换句话说,typescript 不知道interpretation.entries
你也可以窄化interpretation.payload
。
如果您希望它们都被缩小,您需要在PayloadInterpretation
类型中添加另一个鉴别器:
// ...
type PayloadInterpretation<T extends TPayload> = {
type: T['type']; // the new discriminator for the whole PayloadInterpretation
payload: T;
entries: T[];
};
// ...
function f(interpretation: TPayloadInterpretation) {
if (interpretation.type === 'B') { // narrowing the whole interpretation instead of only interpretation.payload
const payload = interpretation.payload; // payload is of type PayloadB
const entries = interpretation.entries; // entries is of type PayloadB[]
}
}
推荐阅读
- video - 自动视频创建 API
- node.js - 即使电子邮件未送达也能成功响应
- android - 如何使用 DevicePolicyManger API 中的 installCaCert 方法?
- r - 轴标签大于ggplot2中的绘图输出
- database - 非规范化多对多关系Hbase
- protractor - 无法单击量角器中的元素
- ruby - 如何在 Ruby 中检查一个完美的正方形?
- angular - Angular 5 AngularFire Firebase 登录闪烁
- sql - SQL TOP 10 已售产品,按 itemno 分组,按客户分组
- javascript - 如何使用 if 语句在 ES6 中声明一个新变量?JavaScript