-
Notifications
You must be signed in to change notification settings - Fork 46.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Improve soundness of ReactDOMFiberInput typings
This is an attempt in improving the soundness for the safe value cast that was added in #11741. We want this to avoid situations like [this one](https://github.com/facebook/react/pull/13362/files/e2dacd1976a70de09c65a4822e190463f08c4feb#r209380079) where we need to remember why we have certain type casts. Additionally we can be sure that we only cast safe values to string. The problem was `getSafeValue()`. It used the (deprecated) `*` type to infer the type which resulted in a passing-through of the implicit `any` of the props `Object`. So `getSafeValue()` was effectively returning `any`. Once I fixed this, I found out that Flow does not allow concatenating all possible types to a string (e.g `"" + false` fails in Flow). To fix this as well, I've opted into making the SafeValue type opaque and added a function that can be used to get the string value. This is sound because we know that SafeValue is already checked. I've verified that the interim function is inlined by the compiler and also looked at a diff of the compiled react-dom bundles to see if I've regressed anything. Seems like we're good.
- Loading branch information
1 parent
725e499
commit b2b714b
Showing
2 changed files
with
44 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
/** | ||
* Copyright (c) 2013-present, Facebook, Inc. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
* | ||
* @flow | ||
*/ | ||
|
||
export opaque type SafeValue = boolean | number | Object | string | null | void; | ||
|
||
// Flow does not allow string concatenation of most non-string types. To work | ||
// around this limitation, we use an opaque type that can only be obtained by | ||
// passing the value through getSafeValue first. | ||
export function safeValueToString(value: SafeValue): string { | ||
return '' + (value: any); | ||
} | ||
|
||
export function getSafeValue(value: mixed): SafeValue { | ||
switch (typeof value) { | ||
case 'boolean': | ||
case 'number': | ||
case 'object': | ||
case 'string': | ||
case 'undefined': | ||
return value; | ||
default: | ||
// function, symbol are assigned as empty strings | ||
return ''; | ||
} | ||
} |