react: Bug: Can't use bigint for the key property

React version: 18.2.0

Steps To Reproduce

  1. 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

Most upvoted comments

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 bigint is not much different than allowing { toString(): string }. But that we wouldn’t want because we can’t make any inference about how semantically useful the toString method would be for keys.

Allowing bigint specifically makes sense since we already do the same for number. https://github.com/DefinitelyTyped/DefinitelyTyped/pull/66723 was already a good start but it should also make the same change to types/react/ts5.0/index.d.ts. Feel free to open a PR making these two changes.

Hey, we just updated to the latest @types/react package version and this has caused some issues when using Keys in places bigint is not supported: https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/66749

My recommendation would be to “stringify” the bigint when passing it to the Key property 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.Key was used for something it used to structurally match but not semantically so this seems fine with me. React.Key is the type key accepts, 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.key would still have the string type.

cc @eps1lon

@LucaDillenburg Hey, thats great! Thanks

Use like this <Div key={4n.toString()} /> By converting the BigInt to a string, 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 Key type. The type doesn’t include bigints BUT imo it should.

So really, what reproduction should I show more than the single line that’s already there?