Skip to content

Commit 3579a89

Browse files
j-piaseckifacebook-github-bot
authored andcommitted
Create a transform for sorting types inside a union (#50468)
Summary: Pull Request resolved: #50468 Changelog: [Internal] Reviewed By: huntie Differential Revision: D72381049 fbshipit-source-id: 9b72f6617b8ac090be9bfd3503d66d89bb701029
1 parent 87f08ca commit 3579a89

File tree

4 files changed

+117
-0
lines changed

4 files changed

+117
-0
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
type AFoo = unknown;
9+
type BFoo = unknown;
10+
type CFoo = unknown;
11+
type DFoo = unknown;
12+
13+
type A = string | number;
14+
type B = DFoo | CFoo | BFoo | AFoo;
15+
type C = AFoo | BFoo | CFoo | DFoo;
16+
type D = BFoo | string | number | BFoo;
17+
type E = string | number | BFoo | AFoo | { foo: string } | { bar: string };
18+
type F = "D" | "C" | "B" | "A";
19+
type G = 3 | 2 | 1 | 0 | "D" | "C" | "B" | "A";
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`sortUnions should sort union members 1`] = `
4+
"/**
5+
* Copyright (c) Meta Platforms, Inc. and affiliates.
6+
*
7+
* This source code is licensed under the MIT license found in the
8+
* LICENSE file in the root directory of this source tree.
9+
*/
10+
11+
type AFoo = unknown;
12+
type BFoo = unknown;
13+
type CFoo = unknown;
14+
type DFoo = unknown;
15+
type A = number | string;
16+
type B = AFoo | BFoo | CFoo | DFoo;
17+
type C = AFoo | BFoo | CFoo | DFoo;
18+
type D = BFoo | BFoo | number | string;
19+
type E = AFoo | BFoo | number | string | {
20+
bar: string;
21+
} | {
22+
foo: string;
23+
};
24+
type F = \\"A\\" | \\"B\\" | \\"C\\" | \\"D\\";
25+
type G = \\"A\\" | \\"B\\" | \\"C\\" | \\"D\\" | 0 | 1 | 2 | 3;"
26+
`;
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow strict-local
8+
* @format
9+
* @oncall react_native
10+
*/
11+
12+
const sortUnionsVisitor = require('../sortUnions.js');
13+
const babel = require('@babel/core');
14+
const {promises: fs} = require('fs');
15+
const path = require('path');
16+
17+
async function translate(code: string): Promise<string> {
18+
const result = await babel.transformAsync(code, {
19+
plugins: ['@babel/plugin-syntax-typescript', sortUnionsVisitor],
20+
});
21+
22+
return result.code;
23+
}
24+
25+
describe('sortUnions', () => {
26+
test('should sort union members', async () => {
27+
const code = await fs.readFile(
28+
path.join(__dirname, '../__fixtures__/sortUnions.d.ts'),
29+
'utf-8',
30+
);
31+
const result = await translate(code);
32+
expect(result).toMatchSnapshot();
33+
});
34+
});
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow strict-local
8+
* @format
9+
* @oncall react_native
10+
*/
11+
12+
import type {PluginObj} from '@babel/core';
13+
14+
import generate from '@babel/generator';
15+
import * as t from '@babel/types';
16+
17+
const visitor: PluginObj<mixed> = {
18+
visitor: {
19+
TSUnionType(path) {
20+
path.node.types.sort((a, b) => {
21+
// push literal types to the end of the union
22+
if (t.isTSTypeLiteral(a) && !t.isTSTypeLiteral(b)) {
23+
return 1;
24+
} else if (!t.isTSTypeLiteral(a) && t.isTSTypeLiteral(b)) {
25+
return -1;
26+
}
27+
28+
// get string representation of the types to correctly handle literals
29+
const aString = generate(a).code;
30+
const bString = generate(b).code;
31+
32+
return aString.localeCompare(bString);
33+
});
34+
},
35+
},
36+
};
37+
38+
module.exports = visitor;

0 commit comments

Comments
 (0)