我想使用接口的默认值创建一个对象,但是在 同时更改对象的结构。例如,对于此界面:
interface IPerson {
name: string
age: number
}
我想创建一个像这样的对象:
const person: IPerson = {
name: {
type: String,
required: true
},
age: {
type: Number,
required: true
}
}
我发现的唯一方法是将对象的类型添加到name
和age
的
IPerson
界面,如下所示:
interface IPerson {
name: string | IProp
age: number | IProp
}
interface IProp {
type: any
required?: boolean
// ...
}
我不想更改原始界面IPerson
。所以我当时
想到这样的事情:
const person: IProperties<IPerson> = {
// use properties of IPerson to determine which key/value pairs are valid in this object
}
答案 0 :(得分:2)
您可以使用mapped type:
interface IPerson {
name: string
age: number
}
type IProperties<T> = {
[K in keyof T]: IProp
}
interface IProp {
type: any
required?: boolean
// …
}
const person: IProperties<IPerson> = {
// …
}
答案 1 :(得分:2)
您可以使用条件类型和映射类型来执行此操作。
interface IPerson {
name: string
age: number
ocupation?: string
}
type PropertyType<T> =
[T] extends [string] ? typeof String :
[T] extends [number] ? typeof Number :
[T] extends [Date] ? typeof Date :
[T] extends [Function] ? typeof Function : // add any other types here
new (...a:any[]) => T // default must be a constructor for whatever T is
type IfRequired<T, K extends keyof T, IfYes, IfNo> =
Pick<T, K> extends Required<Pick<T, K>> ? IfYes : IfNo
type PropertyDefinition<T> = {
[P in keyof T]-?: {
type: PropertyType<Exclude<T[P], null | undefined>> // will not work for unions!
required: IfRequired<T, P, true, false>
}
}
let personDefinition: PropertyDefinition<IPerson> ={
age : {
required: true,
type: Number
},
name: {
required: true,
type: String,
},
ocupation: {
required: false,
type: String
}
}