Socket
Socket
Sign inDemoInstall

downlevel-dts

Package Overview
Dependencies
2
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

downlevel-dts

Convert d.ts to be compatible with older typescript compilers


Version published
Maintainers
1
Created

Package description

What is downlevel-dts?

The downlevel-dts npm package is used to downlevel TypeScript declaration files (.d.ts) to an older version of TypeScript. This is useful for library authors who want to support older versions of TypeScript without maintaining multiple versions of their codebase.

What are downlevel-dts's main functionalities?

Downlevel TypeScript Declarations

This feature allows you to downlevel TypeScript declaration files to a specified TypeScript version. In this example, the input .d.ts file is downleveled to TypeScript version 3.7 and written to the output file.

const downlevelDts = require('downlevel-dts');
const fs = require('fs');

const inputFilePath = 'path/to/input.d.ts';
const outputFilePath = 'path/to/output.d.ts';

const inputDts = fs.readFileSync(inputFilePath, 'utf8');
const outputDts = downlevelDts(inputDts, '3.7');

fs.writeFileSync(outputFilePath, outputDts);

Other packages similar to downlevel-dts

Readme

Source

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();

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

Target

Since the earliest downlevel feature is from Typescript 3.5, downlevel-dts targets Typescript 3.4. In the future the downlevel target may be configurable as Typescript 3.4 becomes less used.

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
  3. To your package.json, add
"typesVersions": {
  "<3.9": { "*": ["ts3.4/*"] }
}
  1. $ cp tsconfig.json ts3.9/tsconfig.json

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

FAQs

Last updated on 04 Aug 2020

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc