I am working on a project using Typescript 4 where I am trying to create an object with discriminated unions. However, it seems that the type safety is not functioning as expected.
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;
Despite defining everything according to the above structure, when I try to create a FilterReportStage object (as shown below), Typescript does not detect any errors with the objects inside the FilterReportStage.metrics
property, even though it correctly reports errors for the top-level metric: FilterMetrics
object. Why could this be happening?
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;
If anyone has insight into why this behavior is occurring, I would greatly appreciate your guidance.