Skip to content

[REGRESSION 6.0.2->7.0.2] Type T<A> not assignable to T<A|B>Β #63733

Description

πŸ”Ž Search Terms

Issue from #63644

πŸ•— Version & Regression Information

  • This changed between versions 6.0.2 and 7.0.2

⏯ Playground Link

No response

πŸ’» Code

import {ChartDataset, ChartTypeRegistry} from "chart.js"

const a: ChartDataset<keyof ChartTypeRegistry> = {} as ChartDataset<"scatter">;

πŸ™ Actual behavior

In TS 7.0.2

test.ts:3:7 - error TS2322: Type 'ChartDataset<"scatter">' is not assignable to type 'ChartDataset<keyof ChartTypeRegistry>'.
  Type 'ChartDataset<"scatter">' is not assignable to type '_DeepPartialObject<{ type: "radar"; } & RadarControllerDatasetOptions & FillerControllerDatasetOptions> & _DeepPartialObject<...> & ChartDatasetProperties<...>'.
    Type 'ChartDataset<"scatter">' is not assignable to type '_DeepPartialObject<{ type: "radar"; } & RadarControllerDatasetOptions & FillerControllerDatasetOptions>'.
      Types of property 'animation' are incompatible.
        Type 'false | _DeepPartialObject<AnimationSpec<"line"> & { onProgress?: ((this: Chart<keyof ChartTypeRegistry, (number | BubbleDataPoint | Point | [...] | null)[], unknown>, event: AnimationEvent) => void) | undefined; onComplete?: ((this: Chart<...>, event: AnimationEvent) => void) | undefined; }> | undefined' is not assignable to type 'false | _DeepPartialObject<AnimationSpec<"radar"> & { onProgress?: ((this: Chart<keyof ChartTypeRegistry, (number | BubbleDataPoint | Point | [...] | null)[], unknown>, event: AnimationEvent) => void) | undefined; onComplete?: ((this: Chart<...>, event: AnimationEvent) => void) | undefined; }> | undefined'.
          Type '_DeepPartialObject<AnimationSpec<"line"> & { onProgress?: ((this: Chart<keyof ChartTypeRegistry, (number | BubbleDataPoint | Point | [...] | null)[], unknown>, event: AnimationEvent) => void) | undefined; onComplete?: ((this: Chart<...>, event: AnimationEvent) => void) | undefined; }>' is not assignable to type 'false | _DeepPartialObject<AnimationSpec<"radar"> & { onProgress?: ((this: Chart<keyof ChartTypeRegistry, (number | BubbleDataPoint | Point | [...] | null)[], unknown>, event: AnimationEvent) => void) | undefined; onComplete?: ((this: Chart<...>, event: AnimationEvent) => void) | undefined; }> | undefined'.
            Type '_DeepPartialObject<AnimationSpec<"line"> & { onProgress?: ((this: Chart<keyof ChartTypeRegistry, (number | BubbleDataPoint | Point | [...] | null)[], unknown>, event: AnimationEvent) => void) | undefined; onComplete?: ((this: Chart<...>, event: AnimationEvent) => void) | undefined; }>' is not assignable to type '_DeepPartialObject<AnimationSpec<"radar"> & { onProgress?: ((this: Chart<keyof ChartTypeRegistry, (number | BubbleDataPoint | Point | [...] | null)[], unknown>, event: AnimationEvent) => void) | undefined; onComplete?: ((this: Chart<...>, event: AnimationEvent) => void) | undefined; }>'.
              Types of property 'duration' are incompatible.
                Type 'number | ((ctx: ScriptableContext<"line">, options: AnyObject) => number | undefined) | undefined' is not assignable to type 'number | ((ctx: ScriptableContext<"radar">, options: AnyObject) => number | undefined) | undefined'.
                  Type '(ctx: ScriptableContext<"line">, options: AnyObject) => number | undefined' is not assignable to type 'number | ((ctx: ScriptableContext<"radar">, options: AnyObject) => number | undefined) | undefined'.
                    Type '(ctx: ScriptableContext<"line">, options: AnyObject) => number | undefined' is not assignable to type '(ctx: ScriptableContext<"radar">, options: AnyObject) => number | undefined'.
                      Types of parameters 'ctx' and 'ctx' are incompatible.
                        Type 'ScriptableContext<"radar">' is not assignable to type 'ScriptableContext<"line">'.
                          Types of property 'dataset' are incompatible.
                            Type '_DeepPartialObject<{ type: "radar"; } & RadarControllerDatasetOptions & FillerControllerDatasetOptions> & _DeepPartialObject<...> & ChartDatasetProperties<...>' is not assignable to type '_DeepPartialObject<{ type: "line"; } & LineControllerDatasetOptions & FillerControllerDatasetOptions> & _DeepPartialObject<...> & ChartDatasetProperties<...>'.
                              Type '_DeepPartialObject<{ type: "radar"; } & RadarControllerDatasetOptions & FillerControllerDatasetOptions> & _DeepPartialObject<...> & ChartDatasetProperties<...>' is not assignable to type '_DeepPartialObject<{ type: "line"; } & LineControllerDatasetOptions & FillerControllerDatasetOptions>'.
                                Types of property 'animation' are incompatible.
                                  Type 'false | _DeepPartialObject<AnimationSpec<"radar"> & { onProgress?: ((this: Chart<keyof ChartTypeRegistry, (number | BubbleDataPoint | Point | [...] | null)[], unknown>, event: AnimationEvent) => void) | undefined; onComplete?: ((this: Chart<...>, event: AnimationEvent) => void) | undefined; }> | undefined' is not assignable to type 'false | _DeepPartialObject<AnimationSpec<"line"> & { onProgress?: ((this: Chart<keyof ChartTypeRegistry, (number | BubbleDataPoint | Point | [...] | null)[], unknown>, event: AnimationEvent) => void) | undefined; onComplete?: ((this: Chart<...>, event: AnimationEvent) => void) | undefined; }> | undefined'.
                                    Type '_DeepPartialObject<AnimationSpec<"radar"> & { onProgress?: ((this: Chart<keyof ChartTypeRegistry, (number | BubbleDataPoint | Point | [...] | null)[], unknown>, event: AnimationEvent) => void) | undefined; onComplete?: ((this: Chart<...>, event: AnimationEvent) => void) | undefined; }>' is not assignable to type 'false | _DeepPartialObject<AnimationSpec<"line"> & { onProgress?: ((this: Chart<keyof ChartTypeRegistry, (number | BubbleDataPoint | Point | [...] | null)[], unknown>, event: AnimationEvent) => void) | undefined; onComplete?: ((this: Chart<...>, event: AnimationEvent) => void) | undefined; }> | undefined'.
                                      Type '_DeepPartialObject<AnimationSpec<"radar"> & { onProgress?: ((this: Chart<keyof ChartTypeRegistry, (number | BubbleDataPoint | Point | [...] | null)[], unknown>, event: AnimationEvent) => void) | undefined; onComplete?: ((this: Chart<...>, event: AnimationEvent) => void) | undefined; }>' is not assignable to type '_DeepPartialObject<AnimationSpec<"line"> & { onProgress?: ((this: Chart<keyof ChartTypeRegistry, (number | BubbleDataPoint | Point | [...] | null)[], unknown>, event: AnimationEvent) => void) | undefined; onComplete?: ((this: Chart<...>, event: AnimationEvent) => void) | undefined; }>'.
                                        Types of property 'duration' are incompatible.
                                          Type 'number | ((ctx: ScriptableContext<"radar">, options: AnyObject) => number | undefined) | undefined' is not assignable to type 'number | ((ctx: ScriptableContext<"line">, options: AnyObject) => number | undefined) | undefined'.
                                            Type '(ctx: ScriptableContext<"radar">, options: AnyObject) => number | undefined' is not assignable to type 'number | ((ctx: ScriptableContext<"line">, options: AnyObject) => number | undefined) | undefined'.
                                              Type '(ctx: ScriptableContext<"radar">, options: AnyObject) => number | undefined' is not assignable to type '(ctx: ScriptableContext<"line">, options: AnyObject) => number | undefined'.
                                                Types of parameters 'ctx' and 'ctx' are incompatible.
                                                  Type 'ScriptableContext<"line">' is not assignable to type 'ScriptableContext<"radar">'.
                                                    Types of property 'dataset' are incompatible.
                                                      Type '_DeepPartialObject<{ type: "line"; } & LineControllerDatasetOptions & FillerControllerDatasetOptions> & _DeepPartialObject<...> & ChartDatasetProperties<...>' is not assignable to type '_DeepPartialObject<{ type: "radar"; } & RadarControllerDatasetOptions & FillerControllerDatasetOptions> & _DeepPartialObject<...> & ChartDatasetProperties<...>'.
                                                        Type '_DeepPartialObject<{ type: "line"; } & LineControllerDatasetOptions & FillerControllerDatasetOptions> & _DeepPartialObject<...> & ChartDatasetProperties<...>' is not assignable to type '_DeepPartialObject<{ type: "radar"; } & RadarControllerDatasetOptions & FillerControllerDatasetOptions>'.
                                                          Types of property 'borderWidth' are incompatible.
                                                            Type 'number | readonly (number | undefined)[] | ((ctx: ScriptableContext<"line">, options: AnyObject) => number | undefined) | undefined' is not assignable to type 'number | readonly (number | undefined)[] | ((ctx: ScriptableContext<"radar">, options: AnyObject) => number | undefined) | undefined'.
                                                              Type '(ctx: ScriptableContext<"line">, options: AnyObject) => number | undefined' is not assignable to type 'number | readonly (number | undefined)[] | ((ctx: ScriptableContext<"radar">, options: AnyObject) => number | undefined) | undefined'.

3 const a: ChartDataset<keyof ChartTypeRegistry> = {} as ChartDataset<"scatter">;
        ~


Found 1 error in test.ts:3

πŸ™‚ Expected behavior

No errors, like in TS 6.0.2.

Additional information about the issue

  • chart.js version 4.5.1
  • both TS version executed with tsc $file --ignoreConfig.

keyof ChartTypeRegistry is "bar"|"line"|"scatter"|"bubble"|"pie"|"doughnut"|"polarArea"|"radar".
So "scatter" is assignable to keyof ChartTypeRegistry.

In TS 6.0.2, ChartDataset<"scatter"> is resolved as:

_DeepPartialObject<{type: "scatter";} & LineControllerDatasetOptions>
& _DeepPartialObject<PluginDatasetOptionsByType<"scatter">> & ChartDatasetProperties<"scatter", (number | Point | null)[]>

And ChartDataset<keyof ChartTypeRegistry> is resolved as:

(               _DeepPartialObject<{type: "bar";} & BarControllerDatasetOptions>
              | _DeepPartialObject<{type: "line";} & LineControllerDatasetOptions & FillerControllerDatasetOptions>
              | _DeepPartialObject<{type: "scatter";} & LineControllerDatasetOptions>
              | _DeepPartialObject<{type: "bubble";} & BubbleControllerDatasetOptions>
              | _DeepPartialObject<...> | _DeepPartialObject<...> | _DeepPartialObject<...> | _DeepPartialObject<...>
) & _DeepPartialObject<...> & ChartDatasetProperties<...>

For unknown reasons, TS 7.0.2 is trying to compare ChartDataset<"scatter"> and ChartDataset<"radar">:

Type 'ChartDataset<"scatter">' is not assignable to type '_DeepPartialObject<{ type: "radar"; } & RadarControllerDatasetOptions & FillerControllerDatasetOptions>' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties.

For reference:

export interface ChartTypeRegistry {
  bar: {
    chartOptions: BarControllerChartOptions;
    datasetOptions: BarControllerDatasetOptions;
    defaultDataPoint: number | [number, number] | null;
    metaExtensions: {};
    parsedDataType: BarParsedData,
    scales: keyof CartesianScaleTypeRegistry;
  };
  line: {
    chartOptions: LineControllerChartOptions;
    datasetOptions: LineControllerDatasetOptions & FillerControllerDatasetOptions;
    defaultDataPoint: ScatterDataPoint | number | null;
    metaExtensions: {};
    parsedDataType: CartesianParsedData;
    scales: keyof CartesianScaleTypeRegistry;
  };
  scatter: {
    chartOptions: ScatterControllerChartOptions;
    datasetOptions: ScatterControllerDatasetOptions;
    defaultDataPoint: ScatterDataPoint | number | null;
    metaExtensions: {};
    parsedDataType: CartesianParsedData;
    scales: keyof CartesianScaleTypeRegistry;
  };
  bubble: {
    chartOptions: unknown;
    datasetOptions: BubbleControllerDatasetOptions;
    defaultDataPoint: BubbleDataPoint;
    metaExtensions: {};
    parsedDataType: BubbleParsedData;
    scales: keyof CartesianScaleTypeRegistry;
  };
  pie: {
    chartOptions: PieControllerChartOptions;
    datasetOptions: PieControllerDatasetOptions;
    defaultDataPoint: PieDataPoint;
    metaExtensions: PieMetaExtensions;
    parsedDataType: number;
    scales: keyof CartesianScaleTypeRegistry;
  };
  doughnut: {
    chartOptions: DoughnutControllerChartOptions;
    datasetOptions: DoughnutControllerDatasetOptions;
    defaultDataPoint: DoughnutDataPoint;
    metaExtensions: DoughnutMetaExtensions;
    parsedDataType: number;
    scales: keyof CartesianScaleTypeRegistry;
  };
  polarArea: {
    chartOptions: PolarAreaControllerChartOptions;
    datasetOptions: PolarAreaControllerDatasetOptions;
    defaultDataPoint: number;
    metaExtensions: {};
    parsedDataType: RadialParsedData;
    scales: keyof RadialScaleTypeRegistry;
  };
  radar: {
    chartOptions: RadarControllerChartOptions;
    datasetOptions: RadarControllerDatasetOptions & FillerControllerDatasetOptions;
    defaultDataPoint: number | null;
    metaExtensions: {};
    parsedDataType: RadialParsedData;
    scales: keyof RadialScaleTypeRegistry;
  };
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Not a DefectThis behavior is one of several equally-correct options

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions