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.

tsc --watch initial build 3x slower than tsc

See original GitHub issue

TypeScript Version: 3.7.0-dev.20191011, 3.6.4, 3.5.2

Search Terms: DeepReadonly slow watch mode


The slowness occurs on a codebase of around 1000 files. I can’t distill it into a repro, but I can show the type that causes the slowness and an alternate type that does not.

I noticed the slowness when I replaced our implementation of DeepReadonly with the one from ts-essentials. One thing I should note in case it is helpful, is that in our codebase DeepReadonly is only used about 80 times. It’s also used nested in some instances, a DeepReadonly type is included as a property of another DeepReadonly type, for example.

Here is the type from ts-essentials:

export type Primitive = string | number | boolean | bigint | symbol | undefined | null;
/** Like Readonly but recursive */
export type DeepReadonly<T> = T extends Primitive
  ? T
  : T extends Function
  ? T
  : T extends Date
  ? T
  : T extends Map<infer K, infer V>
  ? ReadonlyMap<K, V>
  : T extends Set<infer U>
  ? ReadonlySet<U>
  : T extends {}
  ? { readonly [K in keyof T]: DeepReadonly<T[K]> }
  : Readonly<T>;
interface ReadonlySet<ItemType> extends Set<DeepReadonly<ItemType>> {}
interface ReadonlyMap<KeyType, ValueType> extends Map<DeepReadonly<KeyType>, DeepReadonly<ValueType>> {}

Here is ours:

export type Primitive = number | boolean | string | symbol
export type DeepReadonly<T> = T extends ((...args: any[]) => any) | Primitive
  ? T
  : T extends _DeepReadonlyArray<infer U>
  ? _DeepReadonlyArray<U>
  : T extends _DeepReadonlyObject<infer V>
  ? _DeepReadonlyObject<V>
  : T
export interface _DeepReadonlyArray<T> extends ReadonlyArray<DeepReadonly<T>> {}
export type _DeepReadonlyObject<T> = {
  readonly [P in keyof T]: DeepReadonly<T[P]>

Expected behavior:

Both types, when used in our codebase would take a similar amount of time for both a tsc and the initial build of tsc --watch.

Actual behavior:

Our original DeepReadonly takes about 47 seconds to build using tsc. The initial build with tsc --watch also takes a similar amount of time, around 49 seconds.

With the ts-essentials version, a tsc build takes around 48 seconds. The initial build with tsc --watch takes anywhere from 3-5 minutes.

Playground Link:


Related Issues:

None for sure.

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:4
  • Comments:51 (21 by maintainers)

github_iconTop GitHub Comments

Bnayacommented, Oct 28, 2020

These all obscure steps are things that better be done by TypeScript internally. And this is not emit-only issue, but when you have a huge type that being expanded, it will also drastically slowdown intellisense and freeze vscode

lingzcommented, Dec 17, 2019

FWIW, I tracked down the bad declarations using an emit only build, and then used a file size explorer to determine which files were slowing the build down. This got my build a 3x speedup (70secs -> 20secs)

tsc -p ./tsconfig.base.json --declaration --emitDeclarationOnly --extendedDiagnostics --declarationDir ~/Temp/declarations

I used Disk Inventory X and found big files and cut them down.



After: 71001691-b54bfb80-20d5-11ea-9f69-faa5186a614e

Read more comments on GitHub >

github_iconTop Results From Across the Web

tsc - Typescript build with --watch extremely slow when using ...
I have been experimenting with using declaration maps to improve editor performance and have found that enabling declaration: true causes ...
Read more >
Western & Cowboy Hats at Tractor Supply Co.
Shop for Western & Cowboy Hats at Tractor Supply Co. Buy online, free in-store pickup. Shop today!
Read more >
Documentation - tsc CLI Options - TypeScript
Flag Type Default ‑‑allowJs boolean false ‑‑allowUmdGlobalAccess boolean false ‑‑allowUnreachableCode boolean
Read more >
A first look at Bun: is it really 3x faster than Node.js and Deno?
js, plus NPM, plus tsc, plus rollup - but faster. It makes big claims, such as being 3x faster at server-side rendering React....
Read more >
mp5 sd conversion - Serafino Curotti
MP5SD HE (High Efficiency) THE FIRST ONE WE BUILT! ... TSC Conversion MP5-N Description Price; HK 94 to MP5: Install paddle mag release;...
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 Post

No results found

github_iconTop Related Hashnode Post

No results found