在@jcalz 之后,我重写了这个问题。
在此处查看工作示例: TS Playground
我想安全地键入下面的 initFields
方法。这样
a) 仅接受字段作为 prop
(例如,不允许使用 pleaseIgnoreMe
属性)。
b) 仅允许字段包含的类型为 val
。例如。 bar1 只允许使用字符串
class Field<T> {
constructor(public value: T) {}
}
class Item {
initFields(fields: { [P in keyof this]?: any }) {
Object.entries(fields).forEach(
([prop, val]) => ((this[prop as keyof this] as any) = new Field(val))
);
}
}
class Foo extends Item {
bar1!: Field<string>;
bar2!: Field<number>;
pleaseIgnoreMe = "";
init() {
this.initFields({
bar1: "foo",
bar2: 42,
});
}
}
const foo = new Foo();
foo.init();
console.log(foo.bar1.value); // "foo"