使用扩展时,TypeScript能否以与使用联合时相同的方式推断出切换块中的正确类型?

时间:2019-02-13 11:43:17

标签: typescript

在以下情况下,TypeScript正确地将serverMessage的类型推断为ServerInformation

export interface IServerResponse {
    type: 'response';
    cmd: string;
}

export interface ServerError {
    type: 'error',
    errorcode: string;
    cmd?: string;
    trans_id?: string;
    data?: Object;
}

export interface ServerInformation {
    type: 'information',
    info: string;
    data?: Object;
}

export type ServerMessage = IServerResponse | ServerError | ServerInformation;

let serverMessage = message as ServerMessage;

switch (serverMessage.type) {
    case 'information':
        const information: Information = serverMessage.info; // type is inferred correctly
        break;

但是在我看来,这似乎更符合我在其他地方使用的类语法,以用IServerMessage扩展不同类型的消息,而不是将它们组合成ServerMessage类型。 / p>

可以做到吗?我在下面的尝试失败。

export interface IServerMessage {
    type: string;
}

export interface IServerResponse extends IServerMessage {
    type: 'response';
    cmd: string;
}

export interface ServerError extends IServerMessage {
    type: 'error',
    errorcode: string;
    cmd?: string;
    trans_id?: string;
    data?: Object;
}

export interface ServerInformation extends IServerMessage {
    type: 'information',
    info: string;
    data?: Object;
}

let serverMessage: IServerMessage = message ;

switch (serverMessage.type) {
    case 'information':
        const information: Information = serverMessage.info; // type is still inferred as ServerMessage, not the more specific InformationMessage
        break;

1 个答案:

答案 0 :(得分:2)

TL;DR不,您需要工会。

在第一种情况下switch语句起作用的原因是因为您有一个已区分的联合。由于可能的类型列表是已知且有限的,因此该开关可以根据检查来缩小并集的类型。

在第二种情况下,IServerMessage是可以从任何地方以任何类型实现的接口。因此,打字稿没有穷举列表,因此不会进行任何缩小。