繁体   English   中英

Typescript 区分联合类型安全不适用于子对象?

[英]Typescript Discriminated Unions typesafety not working on child object?

我正在使用 Typescript 4 试图创建一个对象,该对象的属性使用可区分联合,但类型安全似乎不起作用?

export enum StageType {
    PULL = 'pull',
    FILTER = 'filter',
}

export enum StageMetricProperty {
    IMPORTED = 'imported',
    SKIPPED = 'skipped',
    PIPED = 'piped',
    ERRORS = 'errors',
    PROCESSED = 'processed',
    SENT = 'sent',
    SAVED = 'saved',
}

// Pull stage metrics
export interface PullMetrics {
    [StageMetricProperty.IMPORTED]?: number;
    [StageMetricProperty.PIPED]?: number;
    [StageMetricProperty.ERRORS]?: number;
}
export interface PullReportStage { 
    type: StageType.PULL;
    name: string;
    args: string[];
    status: StageStatus;
    errors: string[];
    metrics: PullMetrics;
}

// Filter Stage Metrics
export interface FilterMetrics {
    [StageMetricProperty.SKIPPED]?: number;
    [StageMetricProperty.PIPED]?: number;
    [StageMetricProperty.ERRORS]?: number;
}
export interface FilterReportStage {
    type: StageType.FILTER;
    name: string;
    args: string[];
    status: StageStatus;
    errors: string[];
    metrics: FilterMetrics;
}

export type ReportStage =
    | PullReportStage
    | FilterReportStage;

使用上述定义,我尝试创建我的 FilterReportStage 对象(如下),但 Typescript 从不报告FilterReportStage.metrics属性内的对象的任何错误,尽管它确实正确报告了顶级metric: FilterMetrics错误metric: FilterMetrics对象?

const metric: FilterMetrics = {
    [StageMetricProperty.IMPORTED]: 123, // <-- Correctly parsed as invalid (as expected).
    [StageMetricProperty.PIPED]: 123, // <-- Valid
};

const sample = {
    type: StageType.FILTER,
    name: 'utils:command',
    args: [],
    errors: [],
    metrics: {
        [StageMetricProperty.IMPORTED]: 123, // <-- Invalid, Typescript does not report aby errors.
        [StageMetricProperty.PIPED]: 123, // <-- Valid
    } as FilterMetrics,
    status: StageStatus.PENDING
} as FilterReportStage;

有没有人能够指导我为什么会发生这种情况?

当你使用类型断言(例如, as FilterMetrics )时,你告诉打字稿“我比你更了解,所以不要在这里检查我的工作。假设它是我说的类型”。 所以既然你告诉打字稿不要检查你的工作,它就不会。

如果您想要类型检查,则使用标准类型(例如: FilterReportStage ),而不是类型断言:

const sample: FilterReportStage = {
    type: StageType.FILTER,
    name: 'utils:command',
    args: [],
    errors: [],
    metrics: {
        [StageMetricProperty.IMPORTED]: 123, // <--- it points out the error here
        [StageMetricProperty.PIPED]: 123,
    },
    status: StageStatus.PENDING
};

游乐场链接

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM