#typescript #type-inference
#машинописный текст #вывод типа
Вопрос:
Я ищу небольшую помощь в выводе типов, чтобы сузить объединение в TypeScript на основе условного типа.
Наш API принимает набор параметров и проверяет их. Как часть процесса проверки, он нормализует все значения, чтобы упростить последующую обработку. Одним из параметров может быть либо массив строк, либо массив массива строк. При нормализации это значение всегда преобразуется в массив массива строк.
Чтобы избежать необходимости явно выписывать каждый проверенный тип (и поддерживать их) Я пытаюсь вывести проверенные параметры из входящих параметров (которые имеют одинаковые ключи) с разрешенным значением. Например:
type IncomingParams = {
names: string[] | Array<string[]> | undefined
ages: string[] | undefined
}
// Post validation the object is the following
type Validated = {
names: Array<string[]>
ages: string[]
}
Это то, что я придумал, но это не гарантирует, что при наличии объединения оно всегда преобразуется в массив массива.
type ArrayUnion<T> = T[] | T[][];
type Params = {
names: ArrayUnion<string>
ages: string[]
}
type ValidatedParams<P> = {
[K in keyof P]: P[K] extends ArrayUnion<infer U>
? U[][]
: NonNullable<P[K]>;
};
const validated: ValidatedParams<Params> = {} as any;
validated.names // This should be string[][]
validated.ages // This should be string[]
Возможно, Typescript не может различить объединение, поэтому один из вариантов, который я исследовал, — использовать amp; { readonly _sym: unique symbol }
для однозначной идентификации ArrayUnion
, хотя этот подход тоже не сработал.
Я был бы признателен за любую помощь заранее.
Комментарии:
1. Используя ваш код, если я присваиваю
validated.names
переменной (например,const test = validated.names
), кажется, что она имеет ожидаемыйstring[][]
тип.2. Привет @AlbertoRivera, спасибо. Я собрал игровую площадку. как ни странно, я получаю ошибку, которую я записал локально, но, используя игровую площадку, я получаю string[[] — однако
ages
свойство также является string[][], когда оно должно быть string[]3. @J-R основываясь на информации, которую вы предоставили в комментарии выше, это наводит меня на мысль, что в вашем рабочем пространстве / проекте используется более старая версия Typescript, в которой он не мог правильно определить тип. попробуйте обновить project / workspace до более новой версии TS, чтобы узнать, устраняет ли это проблему. Кроме того, может быть полезно включить ваш файл tsconfig.json при публикации вопросов TS, поскольку иногда это может привести к непредвиденным проблемам с конфигурацией, которые не отображаются в playground.
4.
ages
этоstring[][]
потому, что оно расширяетсяArrayUnion
, поскольку это массив. Кроме того, в вашем случае использования, еслиnames
предварительная проверка былаstring[]
, должна ли она бытьstring[][]
после проверки?5. Привет @r3wt спасибо за предложение, я воссоздал его в ссылке playground выше, в которой содержится конфигурация. Я обновил свою локальную версию typescript, и теперь она отражает проблему на игровой площадке.
Ответ №1:
Похоже, что undefined
добавление вызвало некоторые проблемы. Вот решение, работающее на игровой площадке TS