我想把一个对象映射到另一个对象。
由于对象键被限制为字符串的限制,我们只能做字符串到对象的映射。
这是我的变通解决方案,通过映射对象到字符串来进行对象到对象映射,然后通过该字符串从map中获取对象。
type Model = Article | User
type ModelName<M> = M extends Article ? 'Article' : M extends User ? 'User' : never
interface ModelOptionMap {
Article: Prisma.ArticleSelect
User: Prisma.UserSelect
}
type Options<M> = ModelName<M> extends keyof ModelOptionMap ? ModelOptionMap[ModelName<M>] : never
const options: Options<User> = {}
有更好的方法来实现这一点吗?或者是否有任何高级解决方案可以将类型转换为该类型的名称以进行映射,而无需使用长扩展模式?或者有可能做一些像StringOf<T>
一样的事情来获得T的名称作为字符串文字类型?
谢谢@TobiasS。,我找到了一个解决方案,以一种棘手的方式做值到键的映射。
首先选择value,然后将其从接口键中排除。对象应该保持为一个键值对。keyof
,它将获得值的名称。
type ValueOf<T> = T[keyof T]
type PickByValue<T, V extends T[keyof T]> = { [ K in Exclude<keyof T, ValueOf<{ [ P in keyof T ]: T[P] extends V ? never : P }>> ]: T[K] }
type KeyOfValue<T, V extends T[keyof T]> = keyof PickByValue<T, V>
type PickValueByKey<T, K> = K extends keyof T ? T[K] : never
用法:
interface Blueberry { strawberry: boolean; }
interface Car { vehicle: number; asdf: never }
interface Apple { vehicle: number; strawberry: boolean; }
interface ModelMap {
Car: Car
Apple: Apple
Blueberry: Blueberry
}
type AppleName = KeyOfValue<ModelMap, Apple>
回答我的问题:我可以让它变得更简单,像这样使用可怕的扩展链:
interface ModelMap {
Article: Article
User: User
}
type ModelName<M extends ValueOf<ModelMap>> = KeyOfValue<ModelMap, M>
interface ModelOptionMap {
Article: Prisma.ArticleSelect
User: Prisma.UserSelect
}
type Options<M> = ModelName<M> extends keyof ModelOptionMap ? ModelOptionMap[ModelName<M>] : never
const options: Options<User> = {}