Skip to content

Types forgetting key information for infinite keys #44478

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
GuiltyDolphin opened this issue Jun 7, 2021 · 3 comments
Closed

Types forgetting key information for infinite keys #44478

GuiltyDolphin opened this issue Jun 7, 2021 · 3 comments
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@GuiltyDolphin
Copy link

Bug Report

🔎 Search Terms

  • key number string
  • type key loses
  • etc. (I found this hard to search for, please let me know if there's another issues regarding this)

🕗 Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ index but couldn't see any relevant entries, let me know if there are!

⏯ Playground Link

Playground link with relevant code

💻 Code

type KeyIsFinite = {
    [k in 0 | 1 | 2]: k
}

type KeyIsNum = {
    [k in number]: k
}

// if KeyIsFinite[1]: 1 then this will be true
const keyIsFiniteTest: KeyIsFinite[1] extends 1 ? true : false = true;
// if KeyIsNum[1]: 1 then this will be true, but this is actually false, because in KeyIsNum, we are losing information about what `k` is
const keyIsNumTest: KeyIsNum[1] extends 1 ? true : false = true;

// similarly, you can do this with strings
type KeyIsFiniteStr = {
    [k in '0' | '1' | '2']: k
}

type KeyIsStr = {
    [k in string]: k
}

const keyIsFiniteStrTest: KeyIsFiniteStr['1'] extends '1' ? true : false = true;
const keyIsStrTest: KeyIsStr['1'] extends '1' ? true : false = true;

🙁 Actual behavior

We see a type error informing us that keyIsNumTest has type false but is the value true, this is because KeyIsNum is not preserving information about k (I assume), and thus is saying that KeyIsNum[1] = number rather than KeyIsNum[1] = 1. We see that KeyIsFinite[1] = 1, so this appears to be an inconsistency.

🙂 Expected behavior

I would expect KeyIsNum to behave like KeyIsFinite and thus for KeyIsNum[1] = 1 rather than KeyIsNum[1] = number

@jcalz
Copy link
Contributor

jcalz commented Jun 7, 2021

Duplicate of (or strongly related to) #22509

@RyanCavanaugh RyanCavanaugh added Duplicate An existing issue was already created Working as Intended The behavior described is the intended behavior; this is not a bug and removed Duplicate An existing issue was already created labels Jun 7, 2021
@RyanCavanaugh
Copy link
Member

Strong duplicate energy but really just working as intended: mapped types over finite types produce object types with properties, but mapped types over infinite types produce index signatures. Different input different output.

@GuiltyDolphin
Copy link
Author

GuiltyDolphin commented Jun 7, 2021

@jcalz @RyanCavanaugh Yep, I think with "Here I expect string to behave as if it were the union of all possible string literal types." in #22509 this is likely a duplicate. I'd like to just promote that it'd be good for this to work for things like numbers too, but I'll close this in favour of that issue. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug
Projects
None yet
Development

No branches or pull requests

3 participants