GithubHelp home page GithubHelp logo

downlevel-dts's Introduction

downlevel-dts rewrites .d.ts files created by any version of TypeScript so that they work with TypeScript 3.4 or later. It does this by converting code with new features into code that uses equivalent old features. For example, it rewrites accessors to properties, because TypeScript didn't support accessors in .d.ts files until 3.6:

declare class C {
  get x(): number;
}

becomes

declare class C {
  readonly x: number;
}

Note that not all features can be downlevelled. For example, TypeScript 4.0 allows spreading multiple tuple type variables, at any position in a tuple. This is not allowed in previous versions, but has no obvious downlevel emit, so downlevel-dts doesn't attempt to do anything. Be sure to test the output of downlevel-dts with the appropriate version of TypeScript.

Features

Here is the list of features that are downlevelled:

Omit (3.5)

type Less = Omit<T, K>;

becomes

type Less = Pick<T, Exclude<keyof T, K>>;

Omit has had non-builtin implementations since TypeScript 2.2, but became built-in in TypeScript 3.5.

Semantics

Omit is a type alias, so the downlevel should behave exactly the same.

Accessors (3.6)

TypeScript prevented accessors from being in .d.ts files until TypeScript 3.6 because they behave very similarly to properties. However, they behave differently with inheritance, so the distinction can be useful.

declare class C {
  get x(): number;
}

becomes

declare class C {
  readonly x: number;
}

Semantics

The properties emitted downlevel can be overridden in more cases than the original accessors, so the downlevel d.ts will be less strict. See the TypeScript 3.7 release notes for more detail.

asserts assertion guards (3.7)

TypeScript 3.7 introduced the asserts keyword, which provides a way to indicate that a function will throw if a parameter doesn't meet a condition. This allows TypeScript to understand that whatever condition such a function checks must be true for the remainder of the containing scope.

Since there is no way to model this before 3.7, such functions are downlevelled to return void:

declare function assertIsString(val: any, msg?: string): asserts val is string;
declare function assert(val: any, msg?: string): asserts val;

becomes

declare function assertIsString(val: any, msg?: string): void;
declare function assert(val: any, msg?: string): void;

Type-only import/export (3.8)

The downlevel emit is quite simple:

import type { T } from 'x';

becomes

import { T } from "x";

Semantics

The downlevel d.ts will be less strict because a class will be constructable:

declare class C {
}
export type { C };

becomes

declare class C {}
export { C };

and the latter allows construction:

import { C } from "x";
var c = new C();

type modifiers on import/export names (4.5)

The downlevel emit depends on the TypeScript target version and whether type and value imports/exports are mixed.

An import/export declaration with only import/export names that have type modifiers

import { type A, type B } from "x";
export { type A, type B };

becomes:

// TS 3.8+
import type { A, B } from "x";
export type { A, B };

// TS 3.7 or less
import { A, B } from "x";
export { A, B };

A mixed import/export declaration

import { A, type B } from "x";
export { A, type B };

becomes:

// TS 3.8+
import type { B } from "x";
import { A } from "x";
export type { B };
export { A };

// TS 3.7 or less
import { A, B } from "x";
export { A, B };

Semantics

When an import/export declaration has only import/export names with type modifiers, it is emitted as a type-only import/export declaration for TS 3.8+ and as a value import/export declaration for TS 3.7 or less. The latter will be less strict (see type-only import/export).

When type and value imports/exports are mixed, two import/export declarations are emitted for TS 3.8+, one for type-only imports/exports and another one for value imports/exports. For TS 3.7 or less, one value import/export declaration is emitted which will be less strict (see type-only import/export).

#private (3.8)

TypeScript 3.8 supports the new ECMAScript-standard #private properties in addition to its compile-time-only private properties. Since neither are accessible at compile-time, downlevel-dts converts #private properties to compile-time private properties:

declare class C {
  #private
}

It becomes:

declare class C {
  private "#private"`
}

Semantics

The standard emit for any class with a #private property just adds a single #private line. Similarly, a class with a private property adds only the name of the property, but not the type. The d.ts includes only enough information for consumers to avoid interfering with the private property:

class C {
  #x = 1
  private y = 2
}

emits

declare class C {
  #private
  private y
}

which then downlevels to

declare class C {
  private "#private";
  private y;
}

This is incorrect if your class already has a field named "#private". But you really shouldn't do this!

The downlevel d.ts incorrectly prevents consumers from creating a private property themselves named "#private". The consumers of the d.ts also shouldn't do this.

export * from 'x' (3.8)

TypeScript 3.8 supports the new ECMAScript-standard export * as namespace syntax, which is just syntactic sugar for two import/export statements:

export * as ns from 'x';

becomes

import * as ns_1 from "x";
export { ns_1 as ns };

Semantics

The downlevel semantics should be exactly the same as the original.

[named: number, tuple: string, ...members: boolean[]] (4.0)

TypeScript 4.0 supports naming tuple members:

type T = [foo: number, bar: string];

becomes

type T = [/** foo */ number, /** bar */ string];

Semantics

The downlevel semantics are exactly the same as the original, but the TypeScript language service won't be able to show the member names.

in out T (4.7)

Typescript 4.7 supports variance annotations on type parameter declarations:

interface State<in out T> {
    get: () => T;
    set: (value: T) => void;
}

becomes:

interface State<T> {
  get: () => T;
  set: (value: T) => void;
}

Semantics

The downlevel .d.ts omits the variance annotations, which will change the variance in the cases where they were added because the compiler gets it wrong.

Target

Since the earliest downlevel feature is from TypeScript 3.5, downlevel-dts targets TypeScript 3.4 by default. The downlevel target is configurable with --to argument.

Currently, TypeScript 3.0 features like unknown are not downlevelled, nor are there any other plans to support TypeScript 2.x.

Downlevel semantics

Usage

  1. $ npm install downlevel-dts
  2. $ npx downlevel-dts . ts3.4 [--to=3.4]
  3. To your package.json, add
"typesVersions": {
  "<4.0": { "*": ["ts3.4/*"] }
}
  1. $ cp tsconfig.json ts3.9/tsconfig.json

These instructions are modified and simplified from the Definitely Typed ones.

downlevel-dts's People

Contributors

andarist avatar bradzacher avatar chrisguttandin avatar dependabot[bot] avatar deyaaeldeen avatar dsherret avatar g-rath avatar jeremyjonas avatar joshgummersall avatar l2jliga avatar lychyi avatar mattiasbuelens avatar rictic avatar sandersn avatar sisp avatar v-zhzhou avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

downlevel-dts's Issues

Support configurable targets

I'm working on an RFC for how we manage Ember's ecosystem-wide SemVer commitments and TS together (🎉) and one of the elements I'm designing in the midst of it is the use of downlevel-dts to handle breaking changes across minor versions of TS. The current approach of supporting 3.4+ is good enough to get the job done (and in my testing so far, I really appreciate downlevel-dts's level of "it just works"!)—but what we'd really like to be able to do is generate a .d.ts file for each TS version in a given package's support matrix, so that given a set of source files, you'd do something like this:

yarn downlevel-dts --to=3.6 . ts3.6
yarn downlevel-dts --to=3.7 . ts3.7
yarn downlevel-dts --to=3.8 . ts3.8

Deciding automatically which need to be built, a la #26, would also be super neat, but having this level of granularity for us would be really helpful. In particular, we'd prefer that making a change to support a new version of TS doesn't entail changing the types published for users who haven't upgraded TS yet.

For example: we'd really prefer that when 3.8 added support for type-only imports and exports, our emit for 3.7 consumers didn't revert from get semantics to readonly semantics.

If there's interest, I'm very happy to do the implementation work. Having read the source, it looks to be neither trivial nor extremely difficult, and it would be extremely valuable for our use case!

Exports get a semicolon added after

Original d.ts

export { WebResource }

Generated d.ts

export { WebResource };

This is pretty minor, not sure that it hurts anything, but noticed it when looking at diffs.

Public version of package isn't runnable as a command

Something like npx downlevel-dts . ts3.4 doesn't work at the moment, because the version of the package that is published on NPM doesn't have "bin": "index.js", in its package.json.

Instead you get an error: command not found: downlevel-dts

TypeScript 4.8 deprecations

➤ YN0000: DeprecationWarning: 'createExportDeclaration' has been deprecated since v4.8.0. Decorators are no longer supported for this function. Callers should switch to an overload that does not accept a 'decorators' parameter.
➤ YN0000: DeprecationWarning: 'createExportDeclaration' has been deprecated since v4.8.0. Decorators are no longer supported for this function. Callers should switch to an overload that does not accept a 'decorators' parameter.
➤ YN0000: DeprecationWarning: 'createImportDeclaration' has been deprecated since v4.8.0. Decorators are no longer supported for this function. Callers should switch to an overload that does not accept a 'decorators' parameter.
➤ YN0000: DeprecationWarning: 'createPropertyDeclaration' has been deprecated since v4.8.0. Decorators have been combined with modifiers. Callers should switch to an overload that does not accept a 'decorators' parameter.
➤ YN0000: DeprecationWarning: 'createExportDeclaration' has been deprecated since v4.8.0. Decorators are no longer supported for this function. Callers should switch to an overload that does not accept a 'decorators' parameter.
➤ YN0000: DeprecationWarning: 'createExportDeclaration' has been deprecated since v4.8.0. Decorators are no longer supported for this function. Callers should switch to an overload that does not accept a 'decorators' parameter.
➤ YN0000: DeprecationWarning: 'createImportDeclaration' has been deprecated since v4.8.0. Decorators are no longer supported for this function. Callers should switch to an overload that does not accept a 'decorators' parameter.
➤ YN0000: DeprecationWarning: 'createPropertyDeclaration' has been deprecated since v4.8.0. Decorators have been combined with modifiers. Callers should switch to an overload that does not accept a 'decorators' parameter.
➤ YN0000: DeprecationWarning: 'createExportDeclaration' has been deprecated since v4.8.0. Decorators are no longer supported for this function. Callers should switch to an overload that does not accept a 'decorators' parameter.
➤ YN0000: DeprecationWarning: 'createExportDeclaration' has been deprecated since v4.8.0. Decorators are no longer supported for this function. Callers should switch to an overload that does not accept a 'decorators' parameter.
➤ YN0000: DeprecationWarning: 'createImportDeclaration' has been deprecated since v4.8.0. Decorators are no longer supported for this function. Callers should switch to an overload that does not accept a 'decorators' parameter.
➤ YN0000: DeprecationWarning: 'createExportDeclaration' has been deprecated since v4.8.0. Decorators are no longer supported for this function. Callers should switch to an overload that does not accept a 'decorators' parameter.
➤ YN0000: DeprecationWarning: 'createImportDeclaration' has been deprecated since v4.8.0. Decorators are no longer supported for this function. Callers should switch to an overload that does not accept a 'decorators' parameter.
➤ YN0000: DeprecationWarning: 'createExportDeclaration' has been deprecated since v4.8.0. Decorators are no longer supported for this function. Callers should switch to an overload that does not accept a 'decorators' parameter.
➤ YN0000: DeprecationWarning: 'createExportDeclaration' has been deprecated since v4.8.0. Decorators are no longer supported for this function. Callers should switch to an overload that does not accept a 'decorators' parameter.
➤ YN0000: DeprecationWarning: 'createExportDeclaration' has been deprecated since v4.8.0. Decorators are no longer supported for this function. Callers should switch to an overload that does not accept a 'decorators' parameter.
➤ YN0000: DeprecationWarning: 'createImportDeclaration' has been deprecated since v4.8.0. Decorators are no longer supported for this function. Callers should switch to an overload that does not accept a 'decorators' parameter.
➤ YN0000: DeprecationWarning: 'createImportDeclaration' has been deprecated since v4.8.0. Decorators are no longer supported for this function. Callers should switch to an overload that does not accept a 'decorators' parameter.
➤ YN0000: DeprecationWarning: 'createNamedImports' has been deprecated since v4.0.0. Use the appropriate method on 'ts.factory' or the 'factory' supplied by your transformation context instead.
➤ YN0000: DeprecationWarning: 'createImportDeclaration' has been deprecated since v4.8.0. Decorators are no longer supported for this function. Callers should switch to an overload that does not accept a 'decorators' parameter.
➤ YN0000: DeprecationWarning: 'createImportDeclaration' has been deprecated since v4.8.0. Decorators are no longer supported for this function. Callers should switch to an overload that does not accept a 'decorators' parameter.
➤ YN0000: DeprecationWarning: 'createExportDeclaration' has been deprecated since v4.8.0. Decorators are no longer supported for this function. Callers should switch to an overload that does not accept a 'decorators' parameter.
  • createExportDeclaration
  • createImportDeclaration

Reference: https://github.com/microsoft/TypeScript/wiki/API-Breaking-Changes

Input folder duplication on output

I have a project that puts typings into a folder like:

\typings\latest\src\foo.d.ts
\typings\latest\test\bar.d.ts

I try running downlevel-dts against this folder like so npx downlevel-dts typings\latest typings\3.4

I end up with a typings\3.4 folder, but besides having src and test, it also has a path that looks like the path in my monorepo down to where my package.json is (with some of the beginning chopped off):

typings\3.4\dk-for-js\sdk\storage\storage\blob\typings\latest\...

JSDoc comments are incorrectly downleveled

I recently came across an issue with this package where JSDoc comments in getters would get incorrectly downleveled and become regular multi-line comments, which lose all the properties of a JSDoc comment. Here's an example of that taken from the bson package

declare class ObjectId {
	/**
	 * The generation time of this ObjectId instance
	 * @deprecated Please use getTimestamp / createFromTime which returns an int32 epoch
	 */
	get generationTime(): number;
	set generationTime(value: number);
}

becomes

declare class ObjectId {
	/*
	* The generation time of this ObjectId instance
	* @deprecated Please use getTimestamp / createFromTime which returns an int32 epoch
	*/
	generationTime: number;
}

downlevel template literal types

there is missing support for template literal types introduced in TS 4.1

Current Behaviour

export declare type Greeting = `hello ${World}`
declare type World = 'world'

↓↓↓ downlevel-dts ↓↓↓

export declare type Greeting = `hello ${World}`
declare type World = 'world'

Expected Behaviour

export declare type Greeting = `hello ${World}`
declare type World = 'world'

↓↓↓ downlevel-dts ↓↓↓

// Good enough
export declare type Greeting = string
// This would be awesome
export declare type Greeting = `hello world`
declare type World = 'world'

Downlevel private fields

export declare class C {
  #private: string;
}

Proposed emit

declare const private: unique symbol;

export declare class C {
  private [private]: string
}

Map file support

One big difference in the downlevel output is there aren't any map files.

Maybe it's too out of scope, since the original offsets would no longer line up?

Helper methods for getting corresponding accessor and support for static accessors

Hey Nathan,

Thanks for the tweet and this is an excellent use case for the library!

I noticed a few things that might improve this:

  1. Check out the GetAccessorDeclaration#getSetAccessor() helper method. This will help you get the set accessor for a get accessor. A similar method exists on SetAccessorDeclaration. I actually went to look at these methods just a little while ago though and there were a few bugs in them (one of the first methods I wrote in the library). Upgrade to ts-morph 4.3.1 and those issues are fixed (it didn't work outside class declarations and didn't check if isStatic() was equal for both of the nodes). I just did a release right now.
  2. I think you will probably want to take into account the static modifier as well, but I'm not sure how those end up in declaration files.
  3. f.copy(...) will return the copied source file, so you could copy first then modify that source file. That will save an additional trip to the file system.

TODO: Just thought of this, but replaceWithText will also replace the js docs so we need to also include those here.

Also, perhaps I should add a toProperty() method in ts-morph that would change get and set accessors to either property declarations or property assignments depending on the parent.

Output folder being read as input, causes increasingly nesting output folders on each run

We run downlevel-dts as instructed here, with: downlevel-dts . ts3.4 && cp tsconfig.json ./ts3.4/, but on subsequent runs this causes the ./ts3.4 folder to be read as input and then included in the output folder.

We get something like

.
├── lib
├── ...
├── ts3.4
│   ├── ...
│   ├── ts3.4
│   │   ├── ...
│   │   ├── ts3.4

See lit/lit-element#976

Seems like downlevel-dts should exclude the output folder from its inputs.

Generate typesVersions entry in package.json automatically

This is a spin-off of the discussion started in #23. Theoretically it would be possible for this tool to modify the typesVersions entry of a package.json file automatically depending on the features used.

If for example no feature is used which requires any down-leveling no typesVersions property could be created at all.

If for example a private field is used in the codebase downlevel-dts could create a folder with the down-leveled files and at the same time it could update the typesVersions entry to point to that folder.

If for example a private field and accessors are used in the same codebase downlevel-dts could create two folders with the down-leveled files for TypeScript below 3.8 and for TypeScript below 3.7. It could also update the typesVersions entry to point to those two folders.

Incorrect downlevelling of `export * as foo from 'bar'`

Input code:

export * as TSESTree from './ts-estree';

Expected output:

import * as TSESTree from './ts-estree';
export { TSESTree };

Actual output:

import * as TSESTree_1 from './ts-estree';
export { TSESTree_1 as TSESTree } from './ts-estree';

See also

Test input:

// another comment
export * as rex from "./src/test";

Incorrect test output:

import * as rex_1 from "./src/test";
//another comment
export { rex_1 as rex } from "./src/test";

TypeError: Cannot read properties of undefined (reading 'kind') in 0.10.1

Node 18.7.0
TypeScript 4.8.2
Worked in downlevel-dts v 0.10.0; broken in 0.10.1

/home/ntucker/src/rest-hooks/node_modules/downlevel-dts/node_modules/typescript/lib/typescript.js:28803
➤ YN0000:         return node.kind === 162 /* ComputedPropertyName */;
➤ YN0000:                     ^
➤ YN0000: 
➤ YN0000: TypeError: Cannot read properties of undefined (reading 'kind')
➤ YN0000:     at Object.isComputedPropertyName (/home/ntucker/src/rest-hooks/node_modules/downlevel-dts/node_modules/typescript/lib/typescript.js:28803:21)
➤ YN0000:     at Object.createPropertyDeclaration (/home/ntucker/src/rest-hooks/node_modules/downlevel-dts/node_modules/typescript/lib/typescript.js:23287:20)
➤ YN0000:     at transform (/home/ntucker/src/rest-hooks/node_modules/downlevel-dts/index.js:96:20)
➤ YN0000:     at visitNodes (/home/ntucker/src/rest-hooks/node_modules/downlevel-dts/node_modules/typescript/lib/typescript.js:89111:48)
➤ YN0000:     at Object.visitEachChild (/home/ntucker/src/rest-hooks/node_modules/downlevel-dts/node_modules/typescript/lib/typescript.js:89579:362)
➤ YN0000:     at transform (/home/ntucker/src/rest-hooks/node_modules/downlevel-dts/index.js:374:15)
➤ YN0000:     at visitNodes (/home/ntucker/src/rest-hooks/node_modules/downlevel-dts/node_modules/typescript/lib/typescript.js:89111:48)
➤ YN0000:     at visitLexicalEnvironment (/home/ntucker/src/rest-hooks/node_modules/downlevel-dts/node_modules/typescript/lib/typescript.js:89151:22)
➤ YN0000:     at Object.visitEachChild (/home/ntucker/src/rest-hooks/node_modules/downlevel-dts/node_modules/typescript/lib/typescript.js:89702:55)
➤ YN0000:     at transform (/home/ntucker/src/rest-hooks/node_modules/downlevel-dts/index.js:374:15)

Downleveling for `IteratorResult<T, T>`

Downleveling for IteratorResult<T, T>

For TS version < 3.6, IteratorResult takes only one argument -> IteratorResult<T>.
For TS version >= 3.6, IteratorResult takes two arguments -> IteratorResult<T, TReturn = any>(the second one is optional).
TSC compilation would fail for TS version<3.6 when used IteratorResult<T, T>.

IteratorResult in version 3.9

interface IteratorYieldResult<TYield> {
    done?: false;
    value: TYield;
}

interface IteratorReturnResult<TReturn> {
    done: true;
    value: TReturn;
}

type IteratorResult<T, TReturn = any> = IteratorYieldResult<T> | IteratorReturnResult<TReturn>;

IteratorResult in version 3.3

interface IteratorResult<T> {
    done: boolean;
    value: T;
}

It seems appropriate to downlevel IteratorResult<T, T>(or even IteratorResult<T, TReturn>) to IteratorResult<T>.

/cc @jeremymeng @bterlson @ramya-rao-a

Downlevel Awaited

Typescript 4.5 has introduced the Awaited type, which recursively extracts the value inside a promise.

I wanted to contribute to this library, but I got confused about how to implement it since it calls itself:

type Awaited<T> =
    T extends null | undefined ? T : // special case for `null | undefined` when not in `--strictNullChecks` mode
        T extends object & { then(onfulfilled: infer F): any } ? // `await` only unwraps object types with a callable `then`. Non-object types are not unwrapped
            F extends ((value: infer V, ...args: any) => any) ? // if the argument to `then` is callable, extracts the first argument
                Awaited<V> : // recursively unwrap the value
                never : // the argument to `then` was not callable
        T; // non-object or non-thenable

I was able to downlevel it from:

export type K<T> = Awaited<Promise<T>>;

to

export type K<T> = T extends null | undefined ? T : T extends object & {
    then(onfulfilled: infer F): any;
} ? F extends ((value: infer V, ...args: any) => any) ? Awaited<V> : never : T;

As you can see, Awaited calls itself recursively. I tried to look for different similar types that call themselves recursively, but I found none.

I'll be happy to create a PR for this, but I'm not sure how to proceed from here.

You can see here my current attempt.

Downlevel "as const"

as const released in 3.4 makes dealing with constant strings and numbers much easier for library authors. Unfortunately, we have not been able to adopt it and also support typescript <3.4 users. It would be great if this could support down leveling as const.

Currently, I end up doing something like this . Enums are ok for internal usage, but const objects with as const are my preference for publicly exported values. It allows users to easily supply literal values where we expect a union of possible values.

Can we remove the `typescript: next` pin

Is there any reason for it? Currently it means locally, every CI build, every single build of anyone using the AWS CDK we pull down a Typescript nightly. This is a huge amount of energy, bandwidth, etc etc that is just burned because of a config issue or error.

What TS should this be targeting or is it deliberately TS next despite not supporting Typescript 5?

`Omit` not replaced in `extends`

import { RawSourceMap } from 'source-map';

interface FixedRawSourceMap extends Omit<RawSourceMap, 'version'> {
    version: number;
}

Output:

import { RawSourceMap } from 'source-map';
interface FixedRawSourceMap extends Omit<RawSourceMap, 'version'> {
    version: number;
}

Using 0.4.0

Workaround:

import { RawSourceMap } from 'source-map';

type SourceMapWithVersion = Omit<RawSourceMap, 'version'>;

interface FixedRawSourceMap extends SourceMapWithVersion {
  version: number;
}

`asserts` assertion guard not downleveled when used as type annotation

Input

export const foo: (_: number | string) => asserts _ is number = (_) => {};

Output

export declare const foo: (_: number | string) => asserts _ is number;

Workaround

export function foo(_: number | string): asserts _ is number {}

Details

node 12.18.2
downlevel-dts 0.6.0
command node_modules/.bin/downlevel-dts dist/my-package dist/my-package/ts3.4 --to=3.4

Doc comments for converted properties are lost

3.7 d.ts:

    /**
     * Gets the lease Id.
     *
     * @readonly
     * @memberof BlobLeaseClient
     * @type {string}
     */
    get leaseId(): string;

Generated downlevel d.ts:

    readonly leaseId: string;

Would be nice to preserve these comments for IntelliSense

Argument for "Excemption path"?

With typescript 4 we want to make 3 versions of our builds, normal dist with latest (4+) and allso 3.4 and 3.8 versions like:


  "typesVersions": {
    "<3.8": {
      "*": [
        "ts3.4/*"
      ]
    },
    ">=3.8 <4.0": {
      "*": [
        "ts3.8/*"
      ]
    }
  },

And the build script:


    "build": "tsc && downlevel-dts . ts3.4 --to=3.4 && cp tsconfig.json ./ts3.4/ && downlevel-dts . ts3.8 --to=3.8 && cp tsconfig.json ./ts3.8/ && rm -rf ./ts3.8/ts3.4",

Note: I have to remove files from ts3.4 in previous step ending up in ts3.8
If you see anything I did wrong with this I whould love to know. Else it whould be great with an optional argument that excempts files that we do not want to end up in the target.

Nested named tuple types aren't downleveled

Repro (bash):

echo 'export type A = [one: 1, two: [three: 3, four: 4]]' > test.d.ts
npx [email protected] test.d.ts out.d.ts
cat out.d.ts

Result:

export type A = [
    /*one*/ 1,
    /*two*/ [
        three: 3,
        four: 4
    ]
];

Expected:

export type A = [
    /*one*/ 1,
    /*two*/ [
        /*three*/ 3,
        /*four*/ 4
    ]
];

This can be worked around by running downlevel-dts multiple times, but it's hard to know how many!

Support project references/monorepos

Or at least running on multiple directories.

I've added this module to jest (super grateful it exists!), but I have to call downlevel-dts in all the directories in the monorepo (I currently loop through all directories and spawn inside each). It'd be awesome if I could pass a list of all the projects I want to build in addition to the paths

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.