Skip to content

[Bug Report] Wrong keyof type with string index signature #39543

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
meteorlxy opened this issue Jul 10, 2020 · 5 comments
Closed

[Bug Report] Wrong keyof type with string index signature #39543

meteorlxy opened this issue Jul 10, 2020 · 5 comments

Comments

@meteorlxy
Copy link

TypeScript Version: 3.9.x

Search Terms: keyof, index signature

Code

interface Test1 {
    [key: string]: string;
}

type KeyofTest1 = keyof Test1

interface Test2 {
    [key: number]: string;
}

type KeyofTest2 = keyof Test2

Expected behavior:

  • KeyofTest1 should be string
  • KeyofTest2 should be number

Actual behavior:

  • KeyofTest1 is string | number (wrong)
  • KeyofTest2 is number (correct)

Playground Link: https://www.typescriptlang.org/play/?ssl=1&ssc=1&pln=12&pc=1#code/JYOwLgpgTgZghgYwgAgCoQM5gIzIN4BQyxyA2gNYQCeAXMllKAOYC6dDzA3AQL4EFgqABxQBpagHsY6LLgC8ySlSlpMOfqEixEKGWABM+IiQrU6IAK4BbAEbQ29MIxBNufAcLGTpawwqUqevoEQA

Related Issues:

@meteorlxy meteorlxy changed the title Wrong keyof type with string index signature [Bug Report] Wrong keyof type with string index signature Jul 10, 2020
@IllusionMH
Copy link
Contributor

This is by design
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-9.html#support-number-and-symbol-named-properties-with-keyof-and-mapped-types

Given an object type X, keyof X is resolved as follows:

If X contains a string index signature, keyof X is a union of string, number, and the literal types representing symbol-like properties, otherwise

@meteorlxy
Copy link
Author

@IllusionMH Thanks for your quick reply. ❤️

What's the underlay reason of this "by design" ? 🤔

It looks odd and causes some strange type checking error in some third party packages

@IllusionMH
Copy link
Contributor

IllusionMH commented Jul 10, 2020

I think it's because there's no difference between obj[123] and obj["123"] in JS, and TS won't error in case of orders[orderId] if it's orderId is number (which would be annoying).
Any number converted to string will be valid string, however not every string will be valid number therefore same is not applied for number index signature.

I guess it should be OK to use Extract<keyof T, string> if you don't expect to use numbers there.

But I can be wrong here.

@meteorlxy
Copy link
Author

Yeah a possible solution. I'll trying to submit a PR to that package.

Thanks again~ 😄

@ExE-Boss
Copy link
Contributor

Arguably, now that we have #40336 and #40598, keyof should report `${number}` for numeric index signatures.

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