-
Notifications
You must be signed in to change notification settings - Fork 29.9k
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
react: Make value returned by useState Readonly #64099
Conversation
@SpLouk Thank you for submitting this PR! I see this is your first time submitting to DefinitelyTyped 👋 — I'm the local bot who will help you through the process of getting things through. This is a live comment which I will keep updated. 1 package in this PRCode ReviewsThis PR can be merged once it's reviewed. You can test the changes of this PR in the Playground. Status
Once every item on this list is checked, I'll ask you for permission to merge and publish the changes. Diagnostic Information: What the bot saw about this PR{
"type": "info",
"now": "-",
"pr_number": 64099,
"author": "SpLouk",
"headCommitOid": "4665ec5e7744a6fc5d57bc0839b37a29811813cd",
"mergeBaseOid": "7a09beca6be782271dd738e86e33c0a460539916",
"lastPushDate": "2023-01-26T19:40:24.000Z",
"lastActivityDate": "2023-01-30T21:08:25.000Z",
"maintainerBlessed": "Waiting for Code Reviews",
"hasMergeConflict": false,
"isFirstContribution": true,
"tooManyFiles": false,
"hugeChange": false,
"popularityLevel": "Critical",
"pkgInfo": [
{
"name": "react",
"kind": "edit",
"files": [
{
"path": "types/react/package.json",
"kind": "package-meta-ok"
},
{
"path": "types/react/v17/index.d.ts",
"kind": "definition"
}
],
"owners": [
"johnnyreilly",
"bbenezech",
"pzavolinsky",
"ericanderson",
"DovydasNavickas",
"theruther4d",
"guilhermehubner",
"ferdaber",
"jrakotoharisoa",
"pascaloliv",
"hotell",
"franklixuefei",
"Jessidhia",
"saranshkataria",
"lukyth",
"eps1lon",
"zieka",
"dancerphil",
"dimitropoulos",
"disjukr",
"vhfmag",
"hellatan",
"priyanshurav",
"Semigradsky"
],
"addedOwners": [],
"deletedOwners": [],
"popularityLevel": "Critical"
}
],
"reviews": [],
"mainBotCommentID": 1405524743,
"ciResult": "pass"
} |
🔔 @johnnyreilly @bbenezech @pzavolinsky @ericanderson @DovydasNavickas @theruther4d @guilhermehubner @ferdaber @jrakotoharisoa @pascaloliv @Hotell @franklixuefei @Jessidhia @saranshkataria @lukyth @eps1lon @zieka @dancerphil @dimitropoulos @disjukr @vhfmag @hellatan @priyanshurav @Semigradsky — please review this PR in the next few days. Be sure to explicitly select |
I like this suggestion, but it will break a lot of existing code. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this suggestion, but it will break a lot of existing code.
Yeah I can see that. Just had a case today were a component library was expecting a mutable array (which is the default in TypeScript). In those cases, TypeScript would now throw.
Could you test this on some small/medium+ sized repositories to check how many new issues we create with this change?
@@ -918,15 +919,15 @@ declare namespace React { | |||
* @version 16.8.0 | |||
* @see https://reactjs.org/docs/hooks-reference.html#usestate | |||
*/ | |||
function useState<S>(initialState: S | (() => S)): [S, Dispatch<SetStateAction<S>>]; | |||
function useState<S>(initialState: S | (() => S)): [DeepReadonly<S>, Dispatch<SetStateAction<S>>]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would a Readonly
here suffice for the majority of use cases? I'm mainly concerned about perf here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think DeepReadonly would be preferred to prevent mutating nested members of an object.
It's arguable this code has a high chance of being broken already, they just don't know about it |
Inspecting the JavaScript source for this package found some properties that are not in the .d.ts files. react (unpkg)was missing the following properties:
|
Did you run this on some example codebases? What were patterns that it did reject, that we want to reject and what were patterns we don't necessarily want to reject (e.g. due to the ecosystem not having props as readonly in most cases)? |
Yeah, so this will definitely be a breaking change. I didn't anticipate this but
Will cause a type error because I ran our type checker in Faire's codebase locally and got about 20 type errors of this form in a ~100,000 line React/TS codebase. We don't use hooks everywhere yet so that might be a low number for a codebase of that size. Now, in a perfect world, all arrays and objects passed as props should be readonly too, but that isn't the case in our codebase and I'm sure many others. |
Same for our design system at Klarna. Did you catch any actual errors similar to the one explained in the PR description? |
No, no instances of an object actually being mutated. |
Going to go with an internal solution here. |
Please fill in this template.
npm test <package to test>
.Select one of these and delete the others:
If changing an existing definition:
State is immutable, so the return value of useState should be wrapped in the
DeepReadonly
utility type which can prevent accidental mutation.https://github.com/piotrwitek/utility-types/blob/master/src/mapped-types.ts#L396
This will prevent accidental mutation of state. E.g.