TypeScript 某些平台上的堆栈溢出

kmb7vmvb  于 2022-10-29  发布在  TypeScript
关注(0)|答案(9)|浏览(276)

来自@h-joo,地址:#45571

type SomeType = number | string | SomeType[];

declare var obj: { key: SomeType; };

declare namespace jasmine {
    interface Matchers<T> {
        toEqual(expected: Expected<T>): void;
    }

    type Expected<T> = T | {
        [K in keyof T]: ExpectedRecursive<T[K]>;
    }

    type ExpectedRecursive<T> = T | {
        [K in keyof T]: ExpectedRecursive<T[K]>;
    };
}

declare function expect<T>(actual: T): jasmine.Matchers<T>;

expect(obj).toEqual({ key: 'value1' });

tsc或在编辑

> tsc -p src
src/index.ts:19:21 - error TS2589: Type instantiation is excessively deep and possibly infinite.

expect(obj).toEqual({key: 'value1'});
                    ~~~~~~~~~~~~~~~

还是在操场上找我:

simpleWorker.ts:125 Uncaught (in promise) RangeError: Maximum call stack size exceeded
    at isTypeAssignableTo (tsWorker.js:60285)
    at isApplicableIndexType (tsWorker.js:56207)
    at findApplicableIndexInfo (tsWorker.js:56187)
    at getApplicableIndexInfo (tsWorker.js:56236)
    at getPropertyTypeForIndexType (tsWorker.js:58675)
    at getIndexedAccessTypeOrUndefined (tsWorker.js:59018)
    at getIndexedAccessType (tsWorker.js:58940)
    at instantiateTypeWorker (tsWorker.js:60141)
    at instantiateTypeWithAlias (tsWorker.js:60092)
    at instantiateType (tsWorker.js:60075)

这似乎是由于新引入的递归定义
IDBValidKey,而这会导致无限型别具现化。

bnl4lu3b

bnl4lu3b1#

我设法通过将IDBKey替换为

type SomeType = number | string | SomeType[];
xe55xuns

xe55xuns2#

这里的问题是游戏场中的堆栈溢出吗?据我所知,过度的深度错误是预期的行为,在4. 4之前的版本中也会发生。

laximzn5

laximzn53#

顺便说一句,我没有看到堆栈溢出在操场上。

7uhlpewt

7uhlpewt4#

嗯-我想有几件事要注意。
1.“深或可能无限”的错误可能是不可取的,但也许是我们在这里能做的最好的,所以我想这是预期的。

  1. IDBValidKey的变化是引发调查的部分原因,IDBValidKey的定义似乎是正确的,因此,这种类型在Jasmine中表现不佳的事实可能是我们为4.4而不得不吞下的一颗药丸。
    1.堆栈溢出看起来确实是个问题。我在Edge中看到了它,但在Firefox或Node中没有。
q43xntqr

q43xntqr5#

堆栈溢出看起来确实是个问题。我在Edge中看到了它,但在Firefox或Node中没有。
在nightly或4.4.1-rc中,我们已经将nightly中的最大示例化深度从50增加到了500,所以这可能与它有关。

mctunoxg

mctunoxg6#

我想玩深度限制器仍然是一个开放的研究领域

uujelgoq

uujelgoq7#

IDBValidKey的定义从

interface IDBArrayKey extends Array<IDBValidKey> {}
type IDBValidKey = number | string | Date | BufferSource | IDBArrayKey;

不会触发无限示例化,

type IDBValidKey = number | string | Date | BufferSource | IDBValidKey[];

确实触发了无限示例化,这提示了一个问题和一个假设:

*问题:(规范地说)IDBValidKey的这两个定义应该有相同的行为吗?我知道接口技巧是一个长期以来被完全禁止的递归类型别名的解决方案,但是当递归类型别名被支持时,我认为它们的工作方式几乎是一样的。看起来有时候使用中间接口仍然是必要的。
***假设:**这两个赋值之间的行为差异,加上在getNormalizedType中从Relate non-augmenting subtypes without resorting to structural comparison #43624开始进行的替换,是示例化深度限制、堆栈溢出和OOM(按置信度降序列出)中错误增加的主要原因。

xqk2d5yq

xqk2d5yq8#

我也遇到了类似的问题。当我在node项目上运行tsc时,得到了RangeError: Maximum call stack size exceeded
一切都工作正常--这只是在我试图升级到typescript 4.5.3时发生的。它在typescript 4.2.3中工作正常。
FWIW,递归类型是绝对允许的。它们是任何编程语言(更一般地说,上下文无关语法)的标准部分,并且这样做是非常常见的(例如,对于树或编译器等数据结构)。
例如,具有以下条件是100%有效的:

type Tree<T> = { data: T; children: Tree<T>[] }

不幸的是,我得到的stacktrace没有给予任何关于哪种类型导致了问题的指示:

/Users/cbattycapps/{REDACTED}/node_modules/typescript/lib/tsc.js:94444
                throw e;
                ^

RangeError: Maximum call stack size exceeded
    at getRelationKey (/Users/cbattycapps/{REDACTED}/node_modules/typescript/lib/tsc.js:54317:32)
    at recursiveTypeRelatedTo (/Users/cbattycapps/{REDACTED}/node_modules/typescript/lib/tsc.js:52985:26)
    at isRelatedTo (/Users/cbattycapps/{REDACTED}/node_modules/typescript/lib/tsc.js:52645:30)
    at typeRelatedToSomeType (/Users/cbattycapps/{REDACTED}/node_modules/typescript/lib/tsc.js:52869:35)
    at structuredTypeRelatedToWorker (/Users/cbattycapps/{REDACTED}/node_modules/typescript/lib/tsc.js:53099:32)
    at structuredTypeRelatedTo (/Users/cbattycapps/{REDACTED}/node_modules/typescript/lib/tsc.js:53084:30)
    at isRelatedTo (/Users/cbattycapps/{REDACTED}/node_modules/typescript/lib/tsc.js:52642:30)
    at checkTypeRelatedTo (/Users/cbattycapps/{REDACTED}/node_modules/typescript/lib/tsc.js:52314:26)
    at isTypeRelatedTo (/Users/cbattycapps/{REDACTED}/node_modules/typescript/lib/tsc.js:52276:24)
    at isTypeAssignableTo (/Users/cbattycapps/{REDACTED}/node_modules/typescript/lib/tsc.js:51558:20)
oug3syen

oug3syen9#

我刚刚验证了我在typescript4.5.2版本上没有得到这个Maximum call stack size exceeded错误,所以这很可能是在当前最新发布的4.5.3中的一个回归。

相关问题