Typescript: Weird heap overflow when compiling a single line of code with recursive type definition.

Created on 9 Apr 2019  Β·  4Comments  Β·  Source: microsoft/TypeScript


TypeScript Version: [email protected], [email protected]


Search Terms:

  • Heap overflow

Code

type Foo<T> = Extract<{[i in keyof T]: Foo<T[i]>; }[0], 0>;

Expected behavior:
Should print an error for indexing object literal with 0 or using circular references.
Or at least the same behavior as in v3.3.4000:


Output when compiled with [email protected]

image

Actual behavior:

NodeJS standard heap crash report: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory


Details

image

Playground from typescriptlang.com produces in-browser heap memory allocation failure:


Details

image

Playground Link:

Klick me if you are not afraid of crashing your browser's heap

Related Issues:

Bug Crash

Most helpful comment

Great! I think this will be the minimal reproduction of this issue. Thanks a lot!

All 4 comments

Great! I think this will be the minimal reproduction of this issue. Thanks a lot!

The example above produces the expected errors with #30769.

t.ts:1:6 - error TS2456: Type alias 'Foo' circularly references itself.

1 type Foo<T> = Extract<{[i in keyof T]: Foo<T[i]>; }[0], 0>;
       ~~~

t.ts:1:23 - error TS2536: Type '0' cannot be used to index type '{ [i in keyof T]: any; }'.

1 type Foo<T> = Extract<{[i in keyof T]: Foo<T[i]>; }[0], 0>;
                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

t.ts:1:40 - error TS2315: Type 'Foo' is not generic.

1 type Foo<T> = Extract<{[i in keyof T]: Foo<T[i]>; }[0], 0>;
                                         ~~~~~~~~~


Found 3 errors.

Confirmed that this doesn't crash in 3.5.0-rc, although the only error I get is

main.ts:1:23 - error TS2536: Type '0' cannot be used to index type '{ [i in keyof T]: Extract<{ [i in keyof T[i]]: Extract<{ [i in keyof T[i][i]]: Extract<{ [i in keyof T[i][i][i]]: Extract<{ [i in keyof T[i][i][i][i]]: Extract<{ [i in keyof T[i][i][i][i][i]]: Extract<{ [i in keyof T[i][i][i][i][i][i]]: Extract<{ [i in keyof T[i][i][i][i][i][i][i]]: Extract<{ [i in keyof T[i][i][i][i][i][i][i][i]]: Extract<{ [i in keyof T[i][i][i][i][i][i][i][i][i]]: Extract<{ [i in keyof T[i][i][i][i][i][i][i][i][i][i]]: Extract; }[0], 0>; }[0], 0>; }[0], 0>; }[0], 0>; }[0], 0>; }[0], 0>; }[0], 0>; }[0], 0>; }[0], 0>; }[0], 0>; }'.

1 type Foo = Extract<{[i in keyof T]: Foo;

πŸ€”

Talked to @weswigham and this is probably caused by #31354. I think the new output here is not super desirable, but it's not related to this issue per se. If there are new real-world issues with this code or other conditional types in the RC, a new issue is welcomed.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jbondc picture jbondc  Β·  3Comments

seanzer picture seanzer  Β·  3Comments

fwanicka picture fwanicka  Β·  3Comments

wmaurer picture wmaurer  Β·  3Comments

MartynasZilinskas picture MartynasZilinskas  Β·  3Comments