react: Bug: Can't use bigint for the key property
React version: 18.2.0
Steps To Reproduce
- Use bigint as the key property of a jsx object:
<Div key={4n}
The current behavior
Observe a type error, because the accepted type is: number | string | undefined | null.
The expected behavior
The type bigint is acceptable type for the key property.
Come on guys: really floats are keys but ints are not?
About this issue
- Original URL
- State: closed
- Created 10 months ago
- Comments: 15
We have a lot of places where React (or JS) implicitly converts values to strings. TypeScript generally does not allow this at the type level and wants an explicit conversion. So we’ve followed that model for consistency.
Allowing
bigintis not much different than allowing{ toString(): string }. But that we wouldn’t want because we can’t make any inference about how semantically useful thetoStringmethod would be for keys.Allowing
bigintspecifically makes sense since we already do the same fornumber. https://github.com/DefinitelyTyped/DefinitelyTyped/pull/66723 was already a good start but it should also make the same change totypes/react/ts5.0/index.d.ts. Feel free to open a PR making these two changes.Hey, we just updated to the latest
@types/reactpackage version and this has caused some issues when using Keys in places bigint is not supported: https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/66749My recommendation would be to “stringify” the bigint when passing it to the
Keyproperty vs allowing bigint and now requiring to type narrow in cases when bigint is not supported.Fixed in
@types/react@18.2.22.The breakage happens in places where
React.Keywas used for something it used to structurally match but not semantically so this seems fine with me.React.Keyis the typekeyaccepts, not a type you can key arbitrary objects with.React’s runtime have slightly broader implementation than it’s TypeScript types because it is possible to use it without types and it’s also possible to make mistakes with the types. E.g. you can pass all kinds of values to DOM nodes and they will typically be converted to a string. This lets you pass things like objects etc. That’s just common in JavaScript.
React runtime already supports bigint being passed to the key because it’ll convert it to a string key. So it behaves as its string value. That’s also how numbers work.
The TypeScript definitions are sometimes more restrictive than the runtime to catch common mistakes. So I think the ask here is just to update the TypeScript definition to allow it. Note that it’ll still be treated as a string though. Only when passed into the createElement constructor but
element.keywould still have the string type.cc @eps1lon
@LucaDillenburg Hey, thats great! Thanks
Use like this
<Div key={4n.toString()} />By converting theBigIntto astring, you can use it as a key without encountering type errors. However, keep in mind that React will treat these keys as strings, which should work for most scenarios.the bug is simpler than the template expected, sorry if I confused.
The problem is the definition of the
Keytype. The type doesn’t includebigints BUT imo it should.So really, what reproduction should I show more than the single line that’s already there?