Skip to content
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

type inference error #58097

Closed
emeiziying opened this issue Apr 6, 2024 · 3 comments
Closed

type inference error #58097

emeiziying opened this issue Apr 6, 2024 · 3 comments
Labels
Question An issue which isn't directly actionable in code

Comments

@emeiziying
Copy link

emeiziying commented Apr 6, 2024

🔎 Search Terms

Type 'U' cannot be used to index type '{ name: string; capacity: number; } | { name: string; amount: number; }'.

🕗 Version & Regression Information

  • This is a crash
  • This changed between versions ______ and _______
  • This changed in commit or PR _______
  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about _________
  • I was unable to test this on prior versions because _______

⏯ Playground Link

https://www.typescriptlang.org/play?ts=5.4.3#code/JYOwLgpgTgZghgYwgAgMpjpZBvAsAKGWQHcB7KAa2gGcAuHZEOAWwnurClAHMBuZBHAAOiYGACe9EAFdmAI2jIAvgG0AurwJFicKBAAWpadQh0GTVu049+LI+CmyFUZes34lBAhKEp0mCABpCHFkAF5kKnFSGDQMSHcfFAA1OAAbaSCQgB4AFWQIAA9IEAATajiA4PEAPnDIkJjKyBVctRUZeWgNL3wEUhAOZA4A+n8sCLxCEnIqKDMVLSJzFjZkAHIAKVJ9EHWAGgFhUQl6AEZlfaWibEZV+nXc0mYDo5EEMUlkC6Ur6bU-tpdAYjCYFtcVpYNgB1UikUqvOzSBzIAAMlwhtwsa3W6AGEERzHsYHo6N+SwBBCU7gIMGRCDAwAGyAAYnC8gVihAyhVxllxIcAKr1VIZfl5Go1AAUI0g1XouUOADd0pl5chBQBKHBLfqDMDINLAIYRWUQFRm6o9aZGjgAOmYwilUrEEGY2rCdSmywEA2opDSEDtaVI3BdkGYKhVYqtmvcRCUcapBCAA

💻 Code

interface State {
  workers: { name: string; capacity: number }[];
  warehouses: { name: string; amount: number }[];
}

type StateKey = keyof State;
type ValueKey<T extends StateKey> = keyof State[T][number];

const state: State = {
  workers: [
    { name: 'John', capacity: 1 },
    { name: 'Tom', capacity: 1 },
  ],
  warehouses: [
    { name: 'Wood', amount: 0 },
    { name: 'Stone', amount: 0 },
  ],
};

function Foo<T extends StateKey, U = ValueKey<T>>(stateKey: T, valueKey: U) {
  const list = state[stateKey];
  list.map((item) => {
    console.log(item[valueKey]);
  });
}

🙁 Actual behavior

Type 'U' cannot be used to index type '{ name: string; capacity: number; } | { name: string; amount: number; }'.

🙂 Expected behavior

no error report

Additional information about the issue

No response

@jcalz
Copy link
Contributor

jcalz commented Apr 6, 2024

• The issue template has not quite been filled out properly; could you fix it, please?

• Why do you have U = ValueKey<T> instead of U extends ValueKey<T>? Of course you can't use U to index anything if U is unconstrained. If you change to extends you still have the error so I presume this is a typo.

• Where is the bug, exactly? If you're expecting item to be of type State[T][number] instead of the union? Is that the "inference error" you're talking about? That doesn't sound like a bug; the inferred type isn't incorrect. And you could just annotate the type if you don't like the inferred one:

function Foo<
  T extends StateKey,
  U extends keyof State[T][number]
>(stateKey: T, valueKey: U) {
  const list = state[stateKey];
  list.map((item: State[T][number]) => {
    console.log(item[valueKey]);
  });
}

Playground

@emeiziying
Copy link
Author

• The issue template has not quite been filled out properly; could you fix it, please?

• Why do you have U = ValueKey<T> instead of U extends ValueKey<T>? Of course you can't use U to index anything if U is unconstrained. If you change to extends you still have the error so I presume this is a typo.

• Where is the bug, exactly? If you're expecting item to be of type State[T][number] instead of the union? Is that the "inference error" you're talking about? That doesn't sound like a bug; the inferred type isn't incorrect. And you could just annotate the type if you don't like the inferred one:

function Foo<
  T extends StateKey,
  U extends keyof State[T][number]
>(stateKey: T, valueKey: U) {
  const list = state[stateKey];
  list.map((item: State[T][number]) => {
    console.log(item[valueKey]);
  });
}

Playground

Sorry, my ts skills are still in the novice stage. And why should I add type State[T][number] to annotate item? The type of list is State[T], So shouldn’t the type of item be State[T][number]?

@andrewbranch andrewbranch added the Question An issue which isn't directly actionable in code label Apr 8, 2024
@typescript-bot
Copy link
Collaborator

This issue has been marked as "Question" and has seen no recent activity. It has been automatically closed for house-keeping purposes.

@typescript-bot typescript-bot closed this as not planned Won't fix, can't repro, duplicate, stale Apr 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Question An issue which isn't directly actionable in code
Projects
None yet
Development

No branches or pull requests

4 participants