typescript - 打字稿如何从常量属性值推断类型
问题描述
我想从先前定义的常量中获取属性的类型。
const my_constant = {
user: {
props: {
name: {
type: 'string'
}
}
},
media: {
props: {
id: {
type: 'number'
}
}
}
} as const;
type Name = keyof typeof my_constant;
type Constructed<T extends Name> = {
[K in keyof typeof my_constant[T]['props']]: typeof my_constant[T]['props'][K]['type']
// ~~~ Type '"type"' cannot be used to index type ...
}
我不明白为什么我不能使用“类型”作为索引,但我可以使用“道具”。
如果打字稿可以推断出始终存在“道具”属性,为什么它不能推断出始终存在“类型”?
还有另一种方法可以获取类型吗?
我想要实现的是这样的:
const user:Constructed<'user'> = {
name: 'John'
}
const media:Constructed<'media'> = {
id: 123
}
const user2:Constructed<'user'> = {
name: 444
// ~~~ Error
}
const media2:Constructed<'media'> = {
id: 'something'
// ~~~ Error
}
这是带有确切错误的操场链接:
解决方案
Typescript 不能使用字符串来索引常量。它需要正确的密钥。您可以检查对象是否具有该属性type
,也可以使用 Mapped 类型来获取真实类型,而不仅仅是“字符串”。
const my_constant = {
user: {
props: {
name: {
type: 'string'
}
}
},
media: {
props: {
id: {
type: 'number'
}
}
}
} as const;
type Name = keyof typeof my_constant;
type InferType<T> = T extends {type: infer I} ? I : never;
interface Mapped {
string: string;
number: number;
}
type Constructed<T extends Name> = {
[K in keyof typeof my_constant[T]['props']]:
InferType<typeof my_constant[T]['props'][K]> extends keyof Mapped ?
Mapped[InferType<typeof my_constant[T]['props'][K]>] : never
}
推荐阅读
- docker - Docker Hub 上的 Jenkins docker 镜像摘要与本地镜像不匹配
- python - 如何在数据框中检索和存储第二行和第三行元素
- c++ - -Wundef 不对#ifdef 前面的未定义符号发出警告
- python - 根据日期信息重塑熊猫数据框
- mongodb - 无法在 mongodb 中启用分片
- c - 在声明中使用 sizeof
- ios - EPSignature Swift 5.x 问题/每次我想保存我的签名时应用程序崩溃
- c# - 如何交换 2 位数字并找到较大的结果?
- android - 向 Realme 和 Oppo 发送短信
- search - 在图形数据库(neo4j)中搜索用户,其中单个用户可以有多个(相似而不是重复)实例