Skip to content

Regression in some error elaborations involving a target type mixing arrays with non-arraysΒ #62234

@Andarist

Description

@Andarist

πŸ”Ž Search Terms

discriminated discrimination array error elaboration single

πŸ•— Version & Regression Information

⏯ Playground Link

https://www.typescriptlang.org/play/?ts=6.0.0-dev.20250807#code/C4TwDgpgBAyglgOwOYBsIHkBOBBTmCGIAPACoB8UAvFCVAD40DaAugNwBQ7okUAksBAC2VdlHpQA3qLEyAzpgDGALigAiAGYB7Tao4yoAX2kMp+sfOVqARvky7pYgx3YLNCWcCiarAKwCMKvDIaFi4BMT8QhTUplAWKqo2AF6qADTsTpyu7p7ePgBMgYioGDh4hESRghQMAK4IACYQ6ogQDVSS0vHW+CnpmS5uHl6+AMxFwaVhFVXi9U0tCG3RneaKCclpGc7Zw3kALBMloeURAsJ1jc2tDTVQ89dL7TFd6z1921lDnraYAbDFEJlcKVc4rWLdRK9LYDXY-PCFAGTE4gqp3B6LNodRjSWJrSxQj6OdJsL45KC-cZI47AmbnOZXTG3bG4hxxN6ErbE9ikwbk36HalA6ZnIQMhY3dGMm4ssR49kEzbpbm87jQAAymiQcAUlVSUHQKwAFIgwLVgCpeABKKgUdDONV8c75ERiExs-EJLQ6PRmOANFQeTDFX2OYyrMzdTXa3VLABuEEw+vqAGsEJoAO4IMihmT+gD8KnjidzAyaChQtmgcKgKC1OpU0Z1RCDxX1CFqgisiZzZL2vgArEdhadQUJ8uDXpY6zHlVB-QlZJpBBBeA0YTtviMfAA2YdTUdVCfix5Yl6e2v1hRzhdqJcrtcbvu5XwAdn3KLp45PTMnF5nOo3gGd7Lqu679Ju5J5AAHB+tKioILqXBKTxSihZ4Rt0AHXtIt6qPeYFPnywy-EOQoHqizorDicpslhV5zmIeEEY+c4GCSkEkXge7kZ+CHHshp7PFANERv+DFssxoGsdI7E8px8KYO+vHwWOiE-pKspiQqKjYYx87Afh0ngbJHHPhSeCwSpIpqUh9zSqhGlPFp8r0bOkmGSxJkqhwQA

πŸ’» Code

type SingleOrArray<T> = T | T[];

type Item =
  | {
      src: "foo";
    }
  | {
      src: "bar";
    };

const obj1: SingleOrArray<Item> = {
  src: "baz", // βœ… errors nicely at property
};

// ⚠️ no change but reported error is at suboptimal position
const obj2: SingleOrArray<Item> | undefined = {
  src: "baz",
};

// ⚠️ no change but reported error is at suboptimal position
const obj3: SingleOrArray<Item | undefined> = {
  src: "baz",
};

// ⚠️ no change but reported error is at suboptimal position
const obj4: SingleOrArray<Item | undefined> | undefined = {
  src: "baz",
};

const arr1: SingleOrArray<Item> = {
  src: "baz", // βœ… errors nicely at property
};

const arr2: SingleOrArray<Item> | undefined = [
  {
    src: "baz", // βœ… errors nicely at property
  },
];

const arr3: SingleOrArray<Item | undefined> = [
  {
    src: "baz", // βœ… errors nicely at property
  },
];

const arr4: SingleOrArray<Item | undefined> | undefined = [
  {
    src: "baz", // βœ… errors nicely at property
  },
];

type Logic<I, O> = (input: I) => O;

type Item2 =
  | {
      src: "foo";
      id: string;
    }
  | {
      src: Logic<never, unknown>;
      id?: never;
    };

declare const logic: Logic<string, number>;

// ❌ error moved from a property to the variable
const obj5: SingleOrArray<Item2> = {
  src: logic,
  id: "someId",
};

// ❌ error moved from a property to the variable
const obj6: SingleOrArray<Item2> | undefined = {
  src: logic,
  id: "someId",
};

// ❌ error moved from a property to the variable
const obj7: SingleOrArray<Item2 | undefined> = {
  src: logic,
  id: "someId",
};

// ❌ error moved from a property to the variable
const obj8: SingleOrArray<Item2 | undefined> | undefined = {
  src: logic,
  id: "someId",
};

// ⚠️ no change but reported error is at suboptimal position
const arr5: SingleOrArray<Item2> = [
  {
    src: logic,
    id: "someId",
  },
];

// ⚠️ no change but reported error is at suboptimal position
const arr6: SingleOrArray<Item2> | undefined = [
  {
    src: logic,
    id: "someId",
  },
];

const arr7: SingleOrArray<Item2 | undefined> = [
  {
    src: logic,
    id: "someId", // βœ… errors nicely at property
  },
];

const arr8: SingleOrArray<Item2 | undefined> | undefined = [
  {
    src: logic,
    id: "someId", // βœ… errors nicely at property
  },
];

πŸ™ Actual behavior

Some of the errors in the "second group" moved. It is a specific situation with multiple available discriminants.

πŸ™‚ Expected behavior

I'd really expect all of the errors within each "group" to be reported at a property. I especially don't see a reason why | undefined would make the error move to one of the parent nodes.

Additional information about the issue

this was caught here: #61828 (comment)

  1. is this purely an elaboration issue?
  2. or could a heuristic be introduced that would allow for array targets to be eliminated early when discriminating by available object members?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions