TS: Extract type args to tagged template exprs

This commit is contained in:
Asger F
2019-08-22 18:05:49 +01:00
parent 7698240484
commit 45d4b83fc8
10 changed files with 72 additions and 18 deletions

View File

@@ -18,6 +18,15 @@ class TaggedTemplateExpr extends Expr, @taggedtemplateexpr {
/** Gets the tagged template itself. */
TemplateLiteral getTemplate() { result = getChildExpr(1) }
/** Gets the `i`th type argument to the tag of this template literal. */
TypeExpr getTypeArgument(int i) { i >= 0 and result = getChildTypeExpr(2 + i) }
/** Gets a type argument of the tag of this template literal. */
TypeExpr getATypeArgument() { result = getTypeArgument(_) }
/** Gets the number of type arguments appearing on the tag of this template literal. */
int getNumTypeArgument() { result = count(getATypeArgument()) }
override predicate isImpure() { any() }
}

View File

@@ -0,0 +1,5 @@
import javascript
query predicate test_TaggedTemplateLiteralTypeArgument(TaggedTemplateExpr expr, int i, TypeExpr arg) {
arg = expr.getTypeArgument(i)
}

View File

@@ -257,3 +257,7 @@ test_ReturnTypes
test_KeyofTypeExpr
| tst.ts:49:16:49:30 | keyof Interface | tst.ts:49:22:49:30 | Interface |
| tst.ts:113:26:113:35 | keyof Node | tst.ts:113:32:113:35 | Node |
test_TaggedTemplateLiteralTypeArgument
| tst.ts:139:37:139:58 | someTag ... `Hello` | 0 | tst.ts:139:45:139:50 | number |
| tst.ts:140:37:140:66 | someTag ... `Hello` | 0 | tst.ts:140:45:140:50 | number |
| tst.ts:140:37:140:66 | someTag ... `Hello` | 1 | tst.ts:140:53:140:58 | string |

View File

@@ -27,3 +27,4 @@ import RestTypeExpr
import Containers
import ReturnTypes
import KeyofTypeExpr
import TemplateLiterals

View File

@@ -135,3 +135,6 @@ let emptyTuple: [];
let tupleWithRestElement: [number, ...string[]];
let tupleWithOptionalAndRestElements: [number, string?, ...number[]];
let unknownType: unknown;
let taggedTemplateLiteralTypeArg1 = someTag<number>`Hello`;
let taggedTemplateLiteralTypeArg2 = someTag<number, string>`Hello`;

View File

@@ -0,0 +1,8 @@
import { SomeInterface } from 'somwhere1'; // OK
import { AnotherInterface } from 'somwhere2'; // OK
import { foo } from 'somewhere3'; // OK
let x = "world";
console.log(foo<SomeInterface>`Hello world`);
console.log(foo<AnotherInterface>`Hello ${x}`);