我有一些类型定义,如下所示。
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,但是entries的T[]类型仍然是PayloadA[] | PayloadB[]。
我在想,如果typescript知道有效负载的类型T是PayloadA,那么它也应该能够将entries: T[]缩小到entries: PayloadB[]。我知道我可以像这样进行类型转换:
function f(interpretation: TPayloadInterpretation) {
if (interpretation.payload.type === 'B') {
const payloadBInterpretation = interpretation as PayloadInterpretation<PayloadB>;
...
}
}但我的问题是,有没有其他方法可以做到这一点?
代码是typescript playground中的here。
谢谢!
发布于 2021-08-08 12:25:12
当您检查interpretation.payload.type时,您只是缩小了interpretation.payload对象的范围。您实际上并没有做任何事情来缩小interpretation.entries的范围。
换句话说,当你缩小interpretation.payload的范围时,typescript并不知道interpretation.entries也可以缩小。
如果希望同时缩小它们的范围,则需要在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[]
}
}https://stackoverflow.com/questions/68700574
复制相似问题