Git Product home page Git Product logo

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 ohana54 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

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)

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.

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

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'

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 private fields

export declare class C {
  #private: string;
}

Proposed emit

declare const private: unique symbol;

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

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

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

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?

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;
}

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.

`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

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\...

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.

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.

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.

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!

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

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!

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.

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;
}

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";

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.