TS: Unfold aliases in Type.unfold()

This commit is contained in:
Asger F
2019-11-14 16:28:47 +00:00
parent e25ee182a0
commit 8205a59688
4 changed files with 58 additions and 1 deletions

View File

@@ -1816,7 +1816,7 @@ class Type extends @type {
*
* For example, for a type `(S & T) | U` this gets the types `S`, `T`, and `U`.
*/
Type unfold() {
Type unfoldUnionAndIntersection() {
not result instanceof UnionOrIntersectionType and
(
result = this
@@ -1829,6 +1829,27 @@ class Type extends @type {
)
}
/**
* Repeatedly unfolds unions, intersections, and type aliases and gets any of the underlying types,
* or this type itself if it is not a union or intersection.
*
* For example, the type `(S & T) | U` unfolds to `S`, `T`, and `U`.
*
* If this is a type alias, the alias is itself included in the result, but this is not the case for intermediate type aliases.
* For example:
* ```js
* type One = number | string;
* type Two = One | Function & {x: string};
* One; // unfolds to number, string, and One
* Two; // unfolds to number, string, One, Function, {x: string}, and Two
* ```
*/
Type unfold() {
result = unfoldUnionAndIntersection()
or
result = this.(TypeAliasReference).getAliasedType().unfoldUnionAndIntersection()
}
/**
* Holds if this refers to the given named type, or is declared as a subtype thereof,
* or is a union or intersection containing such a type.

View File

@@ -3,15 +3,42 @@ rightHandSide
| tst.ts:2:1:2:16 | type B<T> = T[]; | T[] |
| tst.ts:8:10:8:20 | type C = A; | number |
| tst.ts:15:1:15:23 | type Un ... \| Two; | One \| Two |
| tst.ts:17:1:17:36 | type Un ... mber }; | (One & { x: number; }) \| (Two & { x: number; }) |
| tst.ts:18:1:18:21 | type Un ... Union2; | (One & { x: number; }) \| (Two & { x: number; }) |
| tst.ts:19:1:19:21 | type Un ... Union3; | (One & { x: number; }) \| (Two & { x: number; }) |
| tst.ts:20:1:20:30 | type Un ... number; | number \| (One & { x: number; }) \| (Two & { x: n... |
getAliasedType
| B<T> | T[] |
| B<number> | number[] |
| Union | One \| Two |
| Union2 | (One & { x: number; }) \| (Two & { x: number; }) |
| Union5 | number \| (One & { x: number; }) \| (Two & { x: n... |
getTypeArgument
| B<T> | 0 | T |
| B<number> | 0 | number |
unfold
| B<T> | B<T> |
| B<T> | T[] |
| B<number> | B<number> |
| B<number> | number[] |
| Union | One |
| Union | Two |
| Union | Union |
| Union2 | One |
| Union2 | Two |
| Union2 | Union2 |
| Union2 | { x: number; } |
| Union5 | One |
| Union5 | Two |
| Union5 | Union5 |
| Union5 | number |
| Union5 | { x: number; } |
#select
| tst.ts:1:1:1:16 | type A = number; | tst.ts:1:6:1:6 | A | 0 | tst.ts:1:10:1:15 | number |
| 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[] |
| tst.ts:8:10:8:20 | type C = A; | tst.ts:8:15:8:15 | C | 0 | tst.ts:8:19:8:19 | A |
| 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 |
| 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 } |
| tst.ts:18:1:18:21 | type Un ... Union2; | tst.ts:18:6:18:11 | Union3 | 0 | tst.ts:18:15:18:20 | Union2 |
| tst.ts:19:1:19:21 | type Un ... Union3; | tst.ts:19:6:19:11 | Union4 | 0 | tst.ts:19:15:19:20 | Union3 |
| 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 |

View File

@@ -14,3 +14,7 @@ query Type getAliasedType(TypeAliasReference ref) {
query Type getTypeArgument(TypeAliasReference ref, int n) {
result = ref.getTypeArgument(n)
}
query Type unfold(TypeAliasReference t) {
result = t.unfold()
}

View File

@@ -13,3 +13,8 @@ interface One { a: number }
interface Two { b: number }
type Union = One | Two;
type Union2 = Union & { x: number };
type Union3 = Union2;
type Union4 = Union3;
type Union5 = Union4 | number;