所以,我试图创建一个可以具有动态属性的对象,但我希望IDE能够检测我已经给这个对象的键。
如果我尝试这个例子:
interface Person {
name: string
age: number
}
type dynamicObject = { [key: string]: Person }
const maria: dynamicObject = {
maria: {
name: "Maria",
age: 37
}
}
如果我使用maria.
尝试检测对象maria
的密钥,IDE将不会显示任何内容。
我知道使用泛型类型,我可以使用[P in keyof T]
解决这个问题
interface Person {
name: string
age: number
}
interface Panel<T> {
label: string
fields: (keyof T)[]
}
interface Field<T> {
label: string
value: T
}
interface Form<T> {
panels: { [key : string] : Panel<T> }
fields: { [P in keyof T]?: Field<T[P]> }
}
const form: Form<Person> = {
panels: {
main: {
label: "Panel",
fields: ["name", "age"]
}
},
fields: {
name: {
label: "Name",
value: "Test"
}
}
}
form.panels // not detecting panel keys
form.fields // detecting fields keys
在上面的例子中,我能够从form.fields
中检测到密钥,因为我使用的是具有预定义密钥的类型。但我的目标是能够将这种Form类型转换为相同的东西,但有可能从form.fields
中检测到密钥
那么,有什么函数、重映射类型或方法可以将此索引签名转换为字符串文字来实现这一点呢?
我知道这是可能的,因为有stiches.io这样的库,您可以在其中创建一个具有自定义变体的对象,并且函数会生成一个具有可由IDE检测的自定义键的新对象。我试着看看这背后的魔力,但打字太复杂了,无法理解。
你不能只使用一个类型,需要有一个具有推断返回类型的函数(这也是缝合的作用(。
export type Form = { <T>(values?: U): U }
declare const buildForm: Form;
const form = buildForm({
panels: {
main: {
label: "Panel",
fields: ["name", "age"]
}
},
fields: {
name: {
label: "Name",
value: "Test"
}
}
})
form.panels // OK
form.fields // OK
游乐场