Repository: sandersn/downlevel-dts (js)

Issue:
downlevel template literal types
there is missing support for template literal types introduced in [TS 4.1](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-1.html#template-literal-types)

### Current Behaviour

```ts
export declare type Greeting = `hello ${World}`
declare type World = 'world'
```

↓↓↓ `downlevel-dts` ↓↓↓

```ts
export declare type Greeting = `hello ${World}`
declare type World = 'world'
```

### Expected Behaviour

```ts
export declare type Greeting = `hello ${World}`
declare type World = 'world'
```

↓↓↓ `downlevel-dts` ↓↓↓

```ts
// Good enough
export declare type Greeting = string
// This would be awesome
export declare type Greeting = `hello world`
declare type World = 'world'
```


Pull request description:
feat: downlevel template literal types < 4.1
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-1.html#template-literal-types

Closes #72

Patch:
diff --git a/index.js b/index.js
index 273a154..5fd4338 100644
--- a/index.js
+++ b/index.js
@@ -83,6 +83,12 @@ function doTransform(checker, targetVersion, k) {
       }
     }
 
+    if (semver.lt(targetVersion, "4.1.0") && n.kind === ts.SyntaxKind.TemplateLiteralType) {
+      // TemplateLiteralType added in 4.2
+      // https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-1.html#template-literal-types
+      return ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword)
+    }
+
     if (semver.lt(targetVersion, "3.6.0") && ts.isGetAccessor(n)) {
       // get x(): number => x: number
       let flags = ts.getCombinedModifierFlags(n);


Test patch:
diff --git a/baselines/reference/ts3.4/test.d.ts b/baselines/reference/ts3.4/test.d.ts
index efefc48..dd58496 100644
--- a/baselines/reference/ts3.4/test.d.ts
+++ b/baselines/reference/ts3.4/test.d.ts
@@ -69,3 +69,5 @@ export declare const foo: {
     };
 };
 export type IR = IteratorResult<number>;
+/** Template Literal - supported since 4.1 < should be StringKeyword */
+export type TTemplateLiteral = string;
diff --git a/baselines/reference/ts3.5/test.d.ts b/baselines/reference/ts3.5/test.d.ts
index 0f10b3f..ae9928a 100644
--- a/baselines/reference/ts3.5/test.d.ts
+++ b/baselines/reference/ts3.5/test.d.ts
@@ -69,3 +69,5 @@ export declare const foo: {
     };
 };
 export type IR = IteratorResult<number>;
+/** Template Literal - supported since 4.1 < should be StringKeyword */
+export type TTemplateLiteral = string;
diff --git a/baselines/reference/ts3.6/test.d.ts b/baselines/reference/ts3.6/test.d.ts
index d00369a..5b3a6f1 100644
--- a/baselines/reference/ts3.6/test.d.ts
+++ b/baselines/reference/ts3.6/test.d.ts
@@ -71,3 +71,5 @@ export declare const foo: {
     };
 };
 export type IR = IteratorResult<number, string>;
+/** Template Literal - supported since 4.1 < should be StringKeyword */
+export type TTemplateLiteral = string;
diff --git a/baselines/reference/ts3.7/test.d.ts b/baselines/reference/ts3.7/test.d.ts
index 0062a34..89d6270 100644
--- a/baselines/reference/ts3.7/test.d.ts
+++ b/baselines/reference/ts3.7/test.d.ts
@@ -71,3 +71,5 @@ export declare const foo: {
     };
 };
 export type IR = IteratorResult<number, string>;
+/** Template Literal - supported since 4.1 < should be StringKeyword */
+export type TTemplateLiteral = string;
diff --git a/baselines/reference/ts3.8/test.d.ts b/baselines/reference/ts3.8/test.d.ts
index d006479..f3b3ef8 100644
--- a/baselines/reference/ts3.8/test.d.ts
+++ b/baselines/reference/ts3.8/test.d.ts
@@ -72,3 +72,5 @@ export declare const foo: {
     };
 };
 export type IR = IteratorResult<number, string>;
+/** Template Literal - supported since 4.1 < should be StringKeyword */
+export type TTemplateLiteral = string;
diff --git a/baselines/reference/ts3.9/test.d.ts b/baselines/reference/ts3.9/test.d.ts
index d006479..f3b3ef8 100644
--- a/baselines/reference/ts3.9/test.d.ts
+++ b/baselines/reference/ts3.9/test.d.ts
@@ -72,3 +72,5 @@ export declare const foo: {
     };
 };
 export type IR = IteratorResult<number, string>;
+/** Template Literal - supported since 4.1 < should be StringKeyword */
+export type TTemplateLiteral = string;
diff --git a/baselines/reference/ts4.0/test.d.ts b/baselines/reference/ts4.0/test.d.ts
index 376cd3d..ca58587 100644
--- a/baselines/reference/ts4.0/test.d.ts
+++ b/baselines/reference/ts4.0/test.d.ts
@@ -72,3 +72,5 @@ export declare const foo: {
     };
 };
 export type IR = IteratorResult<number, string>;
+/** Template Literal - supported since 4.1 < should be StringKeyword */
+export type TTemplateLiteral = string;
diff --git a/baselines/reference/ts4.1/test.d.ts b/baselines/reference/ts4.1/test.d.ts
index 376cd3d..3810eea 100644
--- a/baselines/reference/ts4.1/test.d.ts
+++ b/baselines/reference/ts4.1/test.d.ts
@@ -72,3 +72,5 @@ export declare const foo: {
     };
 };
 export type IR = IteratorResult<number, string>;
+/** Template Literal - supported since 4.1 < should be StringKeyword */
+export type TTemplateLiteral = `${string}abc${string}`;
diff --git a/baselines/reference/ts4.2/test.d.ts b/baselines/reference/ts4.2/test.d.ts
index 376cd3d..3810eea 100644
--- a/baselines/reference/ts4.2/test.d.ts
+++ b/baselines/reference/ts4.2/test.d.ts
@@ -72,3 +72,5 @@ export declare const foo: {
     };
 };
 export type IR = IteratorResult<number, string>;
+/** Template Literal - supported since 4.1 < should be StringKeyword */
+export type TTemplateLiteral = `${string}abc${string}`;
diff --git a/baselines/reference/ts4.3/test.d.ts b/baselines/reference/ts4.3/test.d.ts
index 376cd3d..3810eea 100644
--- a/baselines/reference/ts4.3/test.d.ts
+++ b/baselines/reference/ts4.3/test.d.ts
@@ -72,3 +72,5 @@ export declare const foo: {
     };
 };
 export type IR = IteratorResult<number, string>;
+/** Template Literal - supported since 4.1 < should be StringKeyword */
+export type TTemplateLiteral = `${string}abc${string}`;
diff --git a/baselines/reference/ts4.4/test.d.ts b/baselines/reference/ts4.4/test.d.ts
index 376cd3d..3810eea 100644
--- a/baselines/reference/ts4.4/test.d.ts
+++ b/baselines/reference/ts4.4/test.d.ts
@@ -72,3 +72,5 @@ export declare const foo: {
     };
 };
 export type IR = IteratorResult<number, string>;
+/** Template Literal - supported since 4.1 < should be StringKeyword */
+export type TTemplateLiteral = `${string}abc${string}`;
diff --git a/baselines/reference/ts4.5/test.d.ts b/baselines/reference/ts4.5/test.d.ts
index d8582c7..82292d4 100644
--- a/baselines/reference/ts4.5/test.d.ts
+++ b/baselines/reference/ts4.5/test.d.ts
@@ -69,3 +69,5 @@ export declare const foo: {
     };
 };
 export type IR = IteratorResult<number, string>;
+/** Template Literal - supported since 4.1 < should be StringKeyword */
+export type TTemplateLiteral = `${string}abc${string}`;
diff --git a/baselines/reference/ts4.6/test.d.ts b/baselines/reference/ts4.6/test.d.ts
index d8582c7..82292d4 100644
--- a/baselines/reference/ts4.6/test.d.ts
+++ b/baselines/reference/ts4.6/test.d.ts
@@ -69,3 +69,5 @@ export declare const foo: {
     };
 };
 export type IR = IteratorResult<number, string>;
+/** Template Literal - supported since 4.1 < should be StringKeyword */
+export type TTemplateLiteral = `${string}abc${string}`;
diff --git a/baselines/reference/ts4.7/test.d.ts b/baselines/reference/ts4.7/test.d.ts
index d8582c7..82292d4 100644
--- a/baselines/reference/ts4.7/test.d.ts
+++ b/baselines/reference/ts4.7/test.d.ts
@@ -69,3 +69,5 @@ export declare const foo: {
     };
 };
 export type IR = IteratorResult<number, string>;
+/** Template Literal - supported since 4.1 < should be StringKeyword */
+export type TTemplateLiteral = `${string}abc${string}`;
diff --git a/test/test.d.ts b/test/test.d.ts
index 93eb33c..7d516f4 100644
--- a/test/test.d.ts
+++ b/test/test.d.ts
@@ -74,4 +74,7 @@ export declare const foo: {
     };
 };
 
-export type IR = IteratorResult<number, string>;
\ No newline at end of file
+export type IR = IteratorResult<number, string>;
+
+/** Template Literal - supported since 4.1 < should be StringKeyword */
+export type TTemplateLiteral = `${string}abc${string}`;