Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8205a59

Browse files
committed
TS: Unfold aliases in Type.unfold()
1 parent e25ee18 commit 8205a59

4 files changed

Lines changed: 58 additions & 1 deletion

File tree

javascript/ql/src/semmle/javascript/TypeScript.qll

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1816,7 +1816,7 @@ class Type extends @type {
18161816
*
18171817
* For example, for a type `(S & T) | U` this gets the types `S`, `T`, and `U`.
18181818
*/
1819-
Type unfold() {
1819+
Type unfoldUnionAndIntersection() {
18201820
not result instanceof UnionOrIntersectionType and
18211821
(
18221822
result = this
@@ -1829,6 +1829,27 @@ class Type extends @type {
18291829
)
18301830
}
18311831

1832+
/**
1833+
* Repeatedly unfolds unions, intersections, and type aliases and gets any of the underlying types,
1834+
* or this type itself if it is not a union or intersection.
1835+
*
1836+
* For example, the type `(S & T) | U` unfolds to `S`, `T`, and `U`.
1837+
*
1838+
* If this is a type alias, the alias is itself included in the result, but this is not the case for intermediate type aliases.
1839+
* For example:
1840+
* ```js
1841+
* type One = number | string;
1842+
* type Two = One | Function & {x: string};
1843+
* One; // unfolds to number, string, and One
1844+
* Two; // unfolds to number, string, One, Function, {x: string}, and Two
1845+
* ```
1846+
*/
1847+
Type unfold() {
1848+
result = unfoldUnionAndIntersection()
1849+
or
1850+
result = this.(TypeAliasReference).getAliasedType().unfoldUnionAndIntersection()
1851+
}
1852+
18321853
/**
18331854
* Holds if this refers to the given named type, or is declared as a subtype thereof,
18341855
* or is a union or intersection containing such a type.

javascript/ql/test/library-tests/TypeScript/TypeAliases/TypeAliases.expected

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,42 @@ rightHandSide
33
| tst.ts:2:1:2:16 | type B<T> = T[]; | T[] |
44
| tst.ts:8:10:8:20 | type C = A; | number |
55
| tst.ts:15:1:15:23 | type Un ... \| Two; | One \| Two |
6+
| tst.ts:17:1:17:36 | type Un ... mber }; | (One & { x: number; }) \| (Two & { x: number; }) |
7+
| tst.ts:18:1:18:21 | type Un ... Union2; | (One & { x: number; }) \| (Two & { x: number; }) |
8+
| tst.ts:19:1:19:21 | type Un ... Union3; | (One & { x: number; }) \| (Two & { x: number; }) |
9+
| tst.ts:20:1:20:30 | type Un ... number; | number \| (One & { x: number; }) \| (Two & { x: n... |
610
getAliasedType
711
| B<T> | T[] |
812
| B<number> | number[] |
913
| Union | One \| Two |
14+
| Union2 | (One & { x: number; }) \| (Two & { x: number; }) |
15+
| Union5 | number \| (One & { x: number; }) \| (Two & { x: n... |
1016
getTypeArgument
1117
| B<T> | 0 | T |
1218
| B<number> | 0 | number |
19+
unfold
20+
| B<T> | B<T> |
21+
| B<T> | T[] |
22+
| B<number> | B<number> |
23+
| B<number> | number[] |
24+
| Union | One |
25+
| Union | Two |
26+
| Union | Union |
27+
| Union2 | One |
28+
| Union2 | Two |
29+
| Union2 | Union2 |
30+
| Union2 | { x: number; } |
31+
| Union5 | One |
32+
| Union5 | Two |
33+
| Union5 | Union5 |
34+
| Union5 | number |
35+
| Union5 | { x: number; } |
1336
#select
1437
| tst.ts:1:1:1:16 | type A = number; | tst.ts:1:6:1:6 | A | 0 | tst.ts:1:10:1:15 | number |
1538
| tst.ts:2:1:2:16 | type B<T> = T[]; | tst.ts:2:6:2:6 | B | 1 | tst.ts:2:13:2:15 | T[] |
1639
| tst.ts:8:10:8:20 | type C = A; | tst.ts:8:15:8:15 | C | 0 | tst.ts:8:19:8:19 | A |
1740
| tst.ts:15:1:15:23 | type Un ... \| Two; | tst.ts:15:6:15:10 | Union | 0 | tst.ts:15:14:15:22 | One \| Two |
41+
| tst.ts:17:1:17:36 | type Un ... mber }; | tst.ts:17:6:17:11 | Union2 | 0 | tst.ts:17:15:17:35 | Union & ... umber } |
42+
| tst.ts:18:1:18:21 | type Un ... Union2; | tst.ts:18:6:18:11 | Union3 | 0 | tst.ts:18:15:18:20 | Union2 |
43+
| tst.ts:19:1:19:21 | type Un ... Union3; | tst.ts:19:6:19:11 | Union4 | 0 | tst.ts:19:15:19:20 | Union3 |
44+
| tst.ts:20:1:20:30 | type Un ... number; | tst.ts:20:6:20:11 | Union5 | 0 | tst.ts:20:15:20:29 | Union4 \| number |

javascript/ql/test/library-tests/TypeScript/TypeAliases/TypeAliases.ql

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,7 @@ query Type getAliasedType(TypeAliasReference ref) {
1414
query Type getTypeArgument(TypeAliasReference ref, int n) {
1515
result = ref.getTypeArgument(n)
1616
}
17+
18+
query Type unfold(TypeAliasReference t) {
19+
result = t.unfold()
20+
}

javascript/ql/test/library-tests/TypeScript/TypeAliases/tst.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,8 @@ interface One { a: number }
1313
interface Two { b: number }
1414

1515
type Union = One | Two;
16+
17+
type Union2 = Union & { x: number };
18+
type Union3 = Union2;
19+
type Union4 = Union3;
20+
type Union5 = Union4 | number;

0 commit comments

Comments
 (0)