首先,我不能百分之百确定我想做的事是否可能,但我试图描述最好的可能。
interface Property<T> {
value: T
}
interface PropertyBag {
[key: string]: Property<???>
}
function toPlainObject(props: PropertyBag): ??? {
return Object.keys(props)
.reduce((acc, key) => Object.assign(acc, { [key]: props[key].value }), {})
}
一个演示我想做什么的例子:
interface Person {
name: string
age: number
}
const name: Property<string> = { value: 'John Doe' }
const age: Property<number> = { value: 35 }
const props: PropertyBag = { name, age }
const person: Person = toPlainObject(props)
我想知道的是如何输入
toPlainObject
和PropertyBag
的返回类型(类型在哪里???)。这甚至可以使用TS吗? 最佳答案
如果将一个额外的泛型参数添加到PropertyBag
并使用映射类型,则可以做一些接近此的操作:
interface Property<T> {value: T }
type PropertyBag<T> = { [P in keyof T]: Property<T[P]> }
基本上
T
将作为属性包的属性名称和属性类型的持有者。您可以显式地定义一个实例,如下所示:const name: Property<string> = { value: 'John Doe' }
const age: Property<number> = { value: 0 }
let bag : PropertyBag<{ name : string, age: number}> = { age, name };
interface Person { name : string, age: number}
let personBag : PropertyBag<Person > = { age, name };
您还可以创建一个有助于处理类型的函数,这样就不必手动指定所有属性和类型
function createBag<T>(props: PropertyBag<T>):PropertyBag<T> {
return props;
}
const name: Property<string> = { value: 'John Doe' }
const age: Property<number> = { value: 0 }
let bag = createBag({ age, name }); // infered as PropertyBag<{age: number;name: string;}>
当然,你也可以用这个函数:
function toPlainObject<T>(props: PropertyBag<T>): T {
return (Object.keys(props) as Array<keyof T>)
.reduce((acc, key) => Object.assign(acc, { [key]: props[key].value }), {}) as any;
}
const name: Property<string> = { value: 'John Doe' }
const age: Property<number> = { value: 0 }
const person:Person = toPlainObject({ name, age })