question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Tree-shaking d.ts files

See original GitHub issue

Tree-shaking with d.ts files

Importing part of modules using the root index.d.ts file.

🔍 Search Terms

d.ts tree-shaking type import destructuring

✅ Viability Checklist

My suggestion meets these guidelines:

  • This wouldn’t be a breaking change in existing TypeScript/JavaScript code
  • This wouldn’t change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn’t a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
  • This feature would agree with the rest of TypeScript’s Design Goals.

⭐ Suggestion

Parse only the required d.ts file.

💻 Use Cases

We have several modules which uses larger modules with extensive typings, e.g aws-sdk. When we import only S3

import { S3 } from 'aws-sdk';

aws-sdk/index.d.ts got parsed. These bigger modules can add up, increasing required resources for compilation with increased compile time.

If I import S3 directly, then the matching d.ts file parsed only:

import S3 from 'aws-sdk/clients/s3';

I did some experiment changing few of these imports and examined a few tsc traces, parse part went down for 10 seconds to 4, obviously the parsed declaration number went down accordingly.

Tried to look for various config combinations, but found nothing about this.

Issue Analytics

  • State:open
  • Created 2 years ago
  • Comments:12 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
steveetmcommented, Dec 14, 2021

Absolutely no. Or depends on the implementation of this feature, as if it requires slightly modified emitted d.ts, then yes, the corresponding @types/module has to be recompiled.

Then my module can see that it is safe or not to import only the required type from baz, because when we initially emitted baz (which is a separate, third party module), we examined, and decided it is totally safe to use it that way.

Here is some comparison, initial build times:

S3 from ‘aws-sdk/clients/s3’ { S3 } from ‘aws-sdk’
Files: 2486 2816
Lines of Library: 7918 7918
Lines of Definitions: 201784 806500
Lines of TypeScript: 116557 116557
Lines of JavaScript: 0 0
Lines of JSON: 170 170
Lines of Other: 0 0
Nodes of Library: 21726 21726
Nodes of Definitions: 614544 2349462
Nodes of TypeScript: 455155 455162
Nodes of JavaScript: 0 0
Nodes of JSON: 496 496
Nodes of Other: 0 0
Identifiers: 400199 1036550
Symbols: 653745 1022188
Types: 221019 221019
Instantiations: 5217282 5217282
Memory used: 678216K 1175930K
Assignability cache size: 112104 112109
Identity cache size: 14695 14695
Subtype cache size: 8490 8487
Strict subtype cache size: 190061 190061
I/O Read time: 0.24s 0.48s
Parse time: 0.62s 2.31s
ResolveModule time: 0.20s 0.27s
ResolveTypeReference time: 0.00s 0.00s
Program time: 1.20s 3.28s
Bind time: 0.28s 1.37s
Check time: 18.12s 16.34s
I/O Write time: 0.00s 0.00s
printTime time: 0.04s 0.05s
Emit time: 0.04s 0.05s
Total time: 19.64s 21.03s

This is not much, but the memory usage already a lot higher, but not compare the incremental build performance during watch:

S3 from ‘aws-sdk/clients/s3’ { S3 } from ‘aws-sdk’
Files: 2486 2816
Lines of Library: 7918 7918
Lines of Definitions: 201784 806500
Lines of TypeScript: 116557 116557
Lines of JavaScript: 0 0
Lines of JSON: 170 170
Lines of Other: 0 0
Nodes of Library: 21726 21726
Nodes of Definitions: 614544 2349462
Nodes of TypeScript: 455155 455162
Nodes of JavaScript: 0 0
Nodes of JSON: 496 496
Nodes of Other: 0 0
Identifiers: 400199 1036550
Symbols: 218894 587286
Types: 78 78
Instantiations: 0 0
Memory used: 415063K 2687265K
Assignability cache size: 0 0
Identity cache size: 0 0
Subtype cache size: 0 0
Strict subtype cache size: 0 0
I/O Read time: 0.06s 0.45s
Parse time: 0.77s 2.39s
ResolveModule time: 0.22s 0.23s
ResolveTypeReference time: 0.00s 0.00s
Program time: 1.20s 3.29s
Bind time: 0.27s 1.09s
Total time: 1.47s 4.37s

This is now insane. Check the memory usage, the nodes count, and the build time. Nonsense. You can say, lets simply force myself to use ‘aws-sdk/clients/module’. Thats ok, as long as I don’t run into another @types/module which imports a part of aws-sdk in its d.ts file, but using only a part of it. My build time is screwed again. And this is only one big module where tons of unused types got parsed during rebuilds

0reactions
craigphickscommented, Feb 24, 2022

@steveetm Just an observation - with libraries moving towards ESM format and that AWS library being CommonJS, it wouldn’t make sense to develop tree shaking methods for CommonJS libraries. Moreover, with an ESM lib, you could make a proxy intermediate lib using rollup - although I’m not sure that would be less work than manually tree “picking” (as you demonstrated) which is the only current way to select from CommonJS libs.

Read more comments on GitHub >

github_iconTop Results From Across the Web

typescript import *d.ts only instead of source code *.ts
I prefer to do this trick because I want to import a.d.ts only for tree-shaking reasons. I need the type declaration only without...
Read more >
Documentation - Modules .d.ts - TypeScript
Comparing JavaScript to an example DTS. Common CommonJS Patterns. A module using CommonJS patterns uses module.exports to describe the exported values.
Read more >
.d.ts files vs .ts, can someone clear this up for me? : r/typescript
When would I actually write a .d.ts file? Or are they only meant to be submitted to package… ... What are you referring...
Read more >
Reduce JavaScript payloads with tree shaking - web.dev
The utils namespace we've imported tons of modules from is only invoked three times within the main component file. As it turns out,...
Read more >
How to bundle a tree-shakable typescript library with tsup and ...
Tagged with typescript, esbuild, tsup, treeshaking. ... Generates typescript declaration files (e.g. index.d.ts ), useful when you consume ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found