Переполнение кучи во время компиляции TypeScript или как устранить ошибку кругового (бесконечно глубокого) типа - PullRequest
0 голосов
/ 04 апреля 2019

Я занимаюсь разработкой строго типизированной библиотеки утилит для проверки типов. TypeScript 3.4.1 ввел новые ошибки во время компиляции в мой проект. У меня есть Schema тип, который описывает форму некоторого целевого типа. И у меня есть тип UnpackSchema<TSchema extends Schema>, который расширяется до типа, описанного Schema (например, объект схемы времени выполнения { ids: ['number'] } будет описывать статический тип { ids: number[] }).

У меня проблема с круговой ссылкой типа в теле UnpackSchema<>. Поскольку хаки с расширяющимися интерфейсами здесь не помогают, я использую генерацию кода для добавления многих определений UnpackSchema<>, которые ссылаются на себя линейно, пока не достигнут типа never на самом глубоком уровне. Кроме того, я покажу только небольшую часть определения UnpackSchema<>, и даже когда я генерирую 3 экземпляра UnpackSchema<> tsc, некоторое время зависает и не может скомпилировать мой код с переполнением кучи. Поэтому я отчаянно пытаюсь напечатать свой проект, так как даже генерация кода не удается. Это tsc проблема производительности и / или есть ли обходной путь, который я могу использовать, чтобы избежать генерации кода здесь?

Мое упрощенное определение UnpackSchema<> следующее (я не буду показывать определение Schema<>, поскольку оно сложное и выходит за рамки):

export type UnpackSchema<TSchema extends Schema> = (    
    TSchema extends 'string' ? string :
    // ... a lot more cases
    TSchema extends SchemaObj ? UnpackSchemaObject<TSchema> :
    never
);

type SchemaObj = Record<any, Schema>;

// Circular type reference error here
export type UnpackSchemaObject<TObj extends SchemaObj> = MarkUndefinedKeyAsOptional<{
    [TKey in keyof TObj]: UnpackSchema<TObj[TKey]>;
}>;

// adds ? modifier if object's property value contains `undefined` type
type MarkUndefinedKeyAsOptional<TObj> = (
    & TObj[Exclude<keyof TObj, GetUndefinedKeysUnion<TObj>>]
    & Partial<Pick<TObj, GetUndefinedKeysUnion<TObj>>>
);

type GetUndefinedKeysUnion<TObj> = {
    [TKey in keyof TObj]: TObj[TKey] extends undefined ? TKey : never; 
}[keyof TObj];

Отчет о переполнении кучи (при компиляции проекта с tsc):

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...