У меня нет полного ответа, поскольку моя идея во время исправления натолкнулась на проблему, аналогичную той, что была у вас, но я думаю, что предоставленные мной обходные пути могут оказаться полезными, если у вас реальная проблема.
Чтобы найти ответ на свой вопрос, я начал с самого общего вида TableName
, который можно взять. Это keyof typeof mySchema
. Если мы исследуем typeof mySchema[TableName]
, мы обнаружим, что это недискриминационный союз, поэтому keyof
этот тип never
.
Отсюда я разветвляюсь на два направления мысли.
1 , Условный тип
Вы можете добавить условный тип, чтобы взять тип только тогда, когда он существует.
type InstanceConditionalUnion<TableName extends keyof typeof mySchema> = {
[Column in keyof typeof mySchema[TableName]]:
typeof mySchema[TableName][Column] extends {type: any} ?
TypeMap[typeof mySchema[TableName][Column]['type']] : never;
};
Тогда InstanceConditionalUnion<'user'>
эквивалентно UserInstance
, но InstanceConditionalUnion<keyof typeof mySchema>
равно {}
.
2. Тип пересечения
Чтобы использовать что-то вроде Instance<keyof typeof mySchema>
, мы можем преобразовать объединение в пересечение следующим образом:
type InstanceConditionalIntersection<TableName extends keyof typeof mySchema> = {
[Column in keyof UnionToIntersection<typeof mySchema[TableName]>]:
UnionToIntersection<typeof mySchema[TableName]>[Column] extends {type: any} ?
TypeMap[UnionToIntersection<typeof mySchema[TableName]>[Column]['type']] : never;
};
type UnionToIntersection<U> =
(U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never
С UnionToIntersection, взятым из этот ответ .
В этом случае InstanceConditionalIntersection<keyof typeof mySchema>
содержит все ключи как user
, так и message
Увы, этот вид подводит меня к точке, где мой ответ не работает, потому что InstanceIntersection
сталкивается с та же проблема, что и ваш оригинальный тип.
type InstanceIntersection<TableName extends keyof typeof mySchema> = {
[Column in keyof UnionToIntersection<typeof mySchema[TableName]>]:
TypeMap[UnionToIntersection<typeof mySchema[TableName]>[Column]['type']];
};
// this is an error. UnionToIntersection<typeof mySchema[TableName]>[Column]
// doesn't have a 'type' property.