#typescript #generics #compiler-errors #circular-reference #typescript-generics
#typescript #общие сведения #ошибки компилятора #циклическая ссылка #typescript-общие сведения
Вопрос:
Я разрабатываю строго типизированную библиотеку утилит для проверки типов. 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> = (
amp; TObj[Exclude<keyof TObj, GetUndefinedKeysUnion<TObj>>]
amp; Partial<Pick<TObj, GetUndefinedKeysUnion<TObj>>>
);
type GetUndefinedKeysUnion<TObj> = {
[TKey in keyof TObj]: TObj[TKey] extends undefined ? TKey : never;
}[keyof TObj];
Отчет о переполнении кучи (при компиляции проекта с tsc
):
Комментарии:
1. Microsoft / TypeScript # 30663 может иметь отношение?
2. Возможно, @jcalz, спасибо, что указали