Support new Flow variance syntax (#19102)

Co-authored-by: fisker Cheung <lionkay@gmail.com>
This commit is contained in:
Marco Wangandfisker Cheung authored and GitHub committed 2026-04-29 15:42:44 +08:00
1 parent 084046daf8
commit 3ff4e67403
11 files changed
+149 -1

No files matched your search

+19
View File
@@ -0,0 +1,19 @@
#### Add support for `writeonly`, `in`, and `out` variance modifiers (#19102 by @marcoww6)
Support new Flow variance syntax: `writeonly` on object type properties/indexers, and `in T`/`out T` on type parameters.
<!-- prettier-ignore -->
```jsx
// Input
type T = {writeonly foo: string};
type Contravariant<in T> = T;
type Covariant<out T> = T;
// Prettier stable
// SyntaxError
// Prettier main
type T = { writeonly foo: string };
type Contravariant<in T> = T;
type Covariant<out T> = T;
```
+1
View File
@@ -305,6 +305,7 @@
"webstorm",
"Weixin",
"withastro",
"writeonly",
"wxss",
"xdescribe",
"xiechao",
+8 -1
View File
@@ -218,7 +218,14 @@ function printFlow(path, options, print, args) {
return ["?", print("typeAnnotation")];
case "Variance": {
const { kind } = node;
assert.ok(kind === "plus" || kind === "minus" || kind === "readonly");
assert.ok(
kind === "plus" ||
kind === "minus" ||
kind === "readonly" ||
kind === "writeonly" ||
kind === "in" ||
kind === "out",
);
return kind === "plus" ? "+" : kind === "minus" ? "-" : `${kind} `;
}
case "KeyofTypeAnnotation":
@@ -0,0 +1,38 @@
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
exports[`in-out-variance.js format 1`] = `
====================================options=====================================
parsers: ["flow"]
printWidth: 80 (default) |
=====================================input======================================
type Contravariant< in T > = T;
type Covariant< out T > = T;
type Mixed< in T, out U > = T;
type InNamedIn< in in > = void;
type OutNamedOut< out out > = void;
type InWithBound< in T: number > = T;
type OutWithDefault< out T = string > = T;
=====================================output=====================================
type Contravariant<in T> = T;
type Covariant<out T> = T;
type Mixed<in T, out U> = T;
type InNamedIn<in in> = void;
type OutNamedOut<out out> = void;
type InWithBound<in T: number> = T;
type OutWithDefault<out T = string> = T;
================================================================================
`;
@@ -0,0 +1,5 @@
runFormatTest(import.meta, ["flow"], {
errors: {
"babel-flow": true,
},
});
@@ -0,0 +1,13 @@
type Contravariant< in T > = T;
type Covariant< out T > = T;
type Mixed< in T, out U > = T;
type InNamedIn< in in > = void;
type OutNamedOut< out out > = void;
type InWithBound< in T: number > = T;
type OutWithDefault< out T = string > = T;
@@ -24,6 +24,13 @@ type ReadonlyInterface = interface {
readonly prop: string
};
type ReadonlyReservedWords = {
readonly with: string,
readonly default?: string,
readonly enum: number,
readonly new: boolean,
};
=====================================output=====================================
class Route {
static +param: T;
@@ -44,5 +51,12 @@ type ReadonlyInterface = interface {
readonly prop: string,
};
type ReadonlyReservedWords = {
readonly with: string,
readonly default?: string,
readonly enum: number,
readonly new: boolean,
};
================================================================================
`;
+7
View File
@@ -16,3 +16,10 @@ type ReadonlyTuple = [ readonly label: number ];
type ReadonlyInterface = interface {
readonly prop: string
};
type ReadonlyReservedWords = {
readonly with: string,
readonly default?: string,
readonly enum: number,
readonly new: boolean,
};
@@ -0,0 +1,30 @@
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
exports[`writeonly.js format 1`] = `
====================================options=====================================
parsers: ["flow"]
printWidth: 80 (default) |
=====================================input======================================
type WriteonlyObj = {
writeonly foo: string,
writeonly [string]: unknown
};
type WriteonlyReservedWords = {
writeonly with: string,
writeonly default?: string,
};
=====================================output=====================================
type WriteonlyObj = {
writeonly foo: string,
writeonly [string]: unknown,
};
type WriteonlyReservedWords = {
writeonly with: string,
writeonly default?: string,
};
================================================================================
`;
@@ -0,0 +1,5 @@
runFormatTest(import.meta, ["flow"], {
errors: {
"babel-flow": true,
},
});
+9
View File
@@ -0,0 +1,9 @@
type WriteonlyObj = {
writeonly foo: string,
writeonly [string]: unknown
};
type WriteonlyReservedWords = {
writeonly with: string,
writeonly default?: string,
};