Skip to content

Array.prototype.at returns intersection instead of union if one set is a subset of the other #60347

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
KrzysztofKarol opened this issue Oct 26, 2024 · 2 comments

Comments

@KrzysztofKarol
Copy link

🔎 Search Terms

"Array.prototype.at", "Array.at", "item located at the specified index", "intersection", "union", "union type", "subset"

🕗 Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about everything (it's very interesting) but I could not find anything related.

⏯ Playground Link

https://www.typescriptlang.org/play/?target=99&ts=5.7.0-dev.20241026#code/C4TwDgpgBAggTnAhiGUC8UDeVEC4oCMUAvgNoC6A3ALABQoksCyAQullAEb4BMJFNWnQAmEAMYAbRHGhiA9gDsAzsBwIC+eEhRQAPk20tBdectVj20uAVIAGKnQD0jqK6gA9APxOXAdTlwANZKJooqUMKW6gB0iMAAFLYAlILObh7etACWAGZQ8cJJWHSuAEScpVBZChFQnhHRnFD4paI5iACuEqoAbogSHRClgq5p6eMZJVBjE25NWUpQPHTEdD5QACJyEIsKcqoA7gGBdAzQWsgAouzYEPhEZA704OfMIABiN1B3hJRQObx+E8ROIpDIoKZwlYeJo3td9BcPsZaJDVABzKJwHh2J4zSYosKqAAWmJ4sQSyVSLjcXjouXyRKKmCmpRylWqUBJ9SJ0TyLTanW6UD6AyGI2m1NmrlptFGkqleQWUA6CkCewOChWdCAA

💻 Code

type ArrayA = { a: 1 }[];
type ArrayB = { b: 2 }[];

declare const arr1: ArrayA | ArrayB;

const c = arr1[0];
//    ^?
// Works
const d = arr1.at(0);
//    ^?
if (d) {
  "b" in d ? d.b : "default value";
  //           ^?
  //           b is 2
}

// Does not work
type ArrayE = { e: 1 }[];
type ArrayF = { e: 1; f: 2 }[];

declare const arr2: ArrayE | ArrayF;

const g = arr2[0];
//    ^?
// const g: { e: 1 } | { e: 1; f: 2 }
const h = arr2.at(0);
//    ^?
// const h: { e: 1 } | undefined
if (h) {
  "f" in h ? h.f : "default value";
  //           ^?
  //           f is unknown
}

🙁 Actual behavior

In the example, const h type is only an intersection of those two types. Therefore, f property is unknown.

🙂 Expected behavior

const h should a union type of those two types and f property should be 2.

Additional information about the issue

No response

@MartinJohns
Copy link
Contributor

MartinJohns commented Oct 26, 2024

Look up "subtype reduction". It's working as intended / a design limitation.

@jcalz
Copy link
Contributor

jcalz commented Oct 26, 2024

It’s not an intersection, either. An intersection would indeed be incorrect. Maybe you mean the keys are an intersection but that’s quite different.

effectively a duplicate of #55201 and other issues linked within

@KrzysztofKarol KrzysztofKarol closed this as not planned Won't fix, can't repro, duplicate, stale Oct 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants