Typescript 是否可以基于对象属性进行动态键入?
我的结构如下:Typescript 是否可以基于对象属性进行动态键入?,typescript,types,Typescript,Types,我的结构如下: type ErrorObject = { name: string, message: string, } const ALL_ERRORS: ErrorObject[] = [ { name: 'No-empty-name', message: 'You must provide a name', }, { name: 'No-empty-age', message: 'You must provide an
type ErrorObject = {
name: string,
message: string,
}
const ALL_ERRORS: ErrorObject[] = [
{
name: 'No-empty-name',
message: 'You must provide a name',
},
{
name: 'No-empty-age',
message: 'You must provide an age',
},
{
name: 'No-under-18',
message: 'You must be 18+ to continue',
}
]
现在我正在尝试创建一个类型,该类型将定义所有可能的错误
name
s,其结果如下:
type PossibleErrorNames = 'No-empty-name' | 'No-empty-age' | 'No-under-18'
这可以正常工作,但在我的实际项目中,显然数组要大得多,更新这两种类型感觉非常缓慢,因为它们彼此依赖(如果更新一种,则必须更新另一种)
我尝试了以下方法:
const ALL_NAMES = ALL_ERRORS.map(err => `'${err.name}'`).join(' | ')
type PossibleErrorNames = ALL_NAMES
这里的问题是,这是不正确的,因为这将所有\u名称都返回为
“'No-empty-name'|'No-empty age'|'No-under-18'”
这是一个字符串
显然,这是join()的预期行为,但是有没有一种方法可以
将字符串转换为表达式
从所有错误中推断类型的一些可能更优雅的名称
数组?
只要在编译时知道完整数组,就可以使用和执行类似的操作
type ErrorObject = {
name: string,
message: string
}
const ALL_ERRORS = [
{
name: 'No-empty-name',
message: 'You must provide a name',
},
{
name: 'No-empty-age',
message: 'You must provide an age',
},
{
name: 'No-under-18',
message: 'You must be 18+ to continue',
}
] as const // <----- notice here
type PossibleErrorNames = typeof ALL_ERRORS[number]["name"]
// "No-empty-name" | "No-empty-age" | "No-under-18"
类型错误对象={
名称:string,
消息:string
}
常量所有错误=[
{
名称:'没有空名称',
消息:“您必须提供名称”,
},
{
姓名:“无空年龄”,
消息:“您必须提供年龄”,
},
{
姓名:'不得低于18岁',
消息:“您必须年满18岁才能继续”,
}
]as const//实现这一点的唯一方法是将所有错误列表翻转到一个对象中,这将允许您在编译时访问这些类型。您可以按如下方式执行此操作:
const AllErrors={
“没有空名称”:“您必须提供名称”,
“无空年龄”:“您必须提供年龄”,
“不得低于18岁”:“你必须年满18岁才能继续”,
}
//合理化为:键入AllErrorNames=“No empty name”|“No empty age”|“No-under-18”
类型AllErrorNames=类型Allerror的键
//如果你仍然需要它们在一个数组中,你可以使用这样的东西
const allerrorArray=Object.keys(AllErrors).map(errorName=>({name:errorName,message:AllErrors[errorName]}))
否,.join
和其他数组操作在运行时发生。在运行时没有类型系统,它在编译时不再存在。您可以将数组作为一种类型,但它必须在编译时进行转换,因此[“a”,“b”,“c”]
可以转换为“a”|“b”|“c”
,但for(const string of something)arr.push(string)
不是。我自己确实纠正了,@bug answer是另一种唯一的方法;),const断言对我来说是新的!如果你想让你的代码保持现在的状态,请使用他们的答案!