-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Summary: Changelog: [internal] Reviewed By: SamChou19815 Differential Revision: D67115228 fbshipit-source-id: 5514bc383036546241f7dabb07127156966c9a57
- Loading branch information
1 parent
8e5ecac
commit ab16bba
Showing
2 changed files
with
79 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
--- | ||
title: Const Expressions | ||
slug: /types/const-expression | ||
--- | ||
|
||
Sometimes it is useful to specifiy that a literal expression is expected to be immutable. | ||
In such cases, you can annotate the expression with the `as const` modifier. We | ||
refer to these expressions as const-expressions. | ||
|
||
## Typing for Const Expressions {#toc-const-expression-typing} | ||
|
||
The inferred type of const-expressions is the [singleton type](../literals) for primitive values | ||
and the read-only versions for container types. Array literals are inferred as tuple types. | ||
|
||
Here are some examples of primitive values: | ||
```js | ||
42 as const; // inferred type is 42 | ||
|
||
"hello" as const; // inferred type is "hello" | ||
``` | ||
|
||
Containers become read-only and the modifier is applied deeply | ||
```js | ||
{ f: 42 } as const; // {+f: 42} | ||
|
||
[42, "hello"] as const; // $ReadOnly<[42, "hello"]> | ||
|
||
{ f: { g: 42 } } as const; // {+f: {+g: 42}} | ||
``` | ||
|
||
Note that the effect of the modifier does not persist through variables. For example | ||
in | ||
```js | ||
const nonConstObject = { g: 42 }; | ||
const constObject = { f: nonConstObject } as const; | ||
``` | ||
the type of `nonConstObject` will be `{g: number}` and the type of `constObject` will | ||
be `{+f: {g: number}}`. In other words, only the top-level property `prop` will | ||
be read-only. | ||
|
||
Finally, it is an error to apply `as const` to non-literal expressions: | ||
```js flow-check | ||
const x = 1; | ||
const y = x as const; | ||
``` | ||
|
||
## Typical const-expression example {#toc-const-expression-example} | ||
|
||
A common pattern where const-expressions are useful is in enum-like | ||
structures that are not expected to be mutated. For example | ||
```js | ||
export const STATUS = { | ||
INIT: 'INIT', | ||
LOADING: 'LOADING', | ||
SUCCESS: 'SUCCESS', | ||
ERROR: 'ERROR', | ||
} as const; | ||
``` | ||
The type of `STATUS.INIT` is `"INIT"`, the type of `STATUS.LOADING` is `"LOADING"` and so on. | ||
|
||
With this definition it is also possible to effectively lift the values of the various fields | ||
to type annotations. For example | ||
```js | ||
type State = | ||
| { +kind: typeof STATUS.INIT; } | ||
| { +kind: typeof STATUS.LOADING; progress: number; } | ||
| { +kind: typeof STATUS.SUCCESS; result: string; } | ||
| { +kind: typeof STATUS.ERROR; msg: string; }; | ||
``` | ||
Without the use of `as const` the type `typeof STATUS.INIT` would be `string`, which | ||
would make it unsuitable as a distinguishing tag in a disjoint union. | ||
|
||
## Adoption of `as const` syntax | ||
To use the `as const` syntax, you need to upgrade your infrastructure: | ||
- Flow and Flow Parser: 0.256+ | ||
- Prettier: 3.1+ | ||
- Babel: use the [babel-plugin-syntax-hermes-parser](https://www.npmjs.com/package/babel-plugin-syntax-hermes-parser) plugin version 0.19+, see our [Babel guide](../../tools/babel) for more details. | ||
- ESLint: use [hermes-eslint](https://www.npmjs.com/package/hermes-eslint) plugin version 0.19+, see our [ESLint guide](../../tools/eslint) for more details. |
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