我正在尝试在打字稿中创建一个通用模型类,该子类可以扩展该类,以便在超类中创建自动HTTP数据以对模型处理方法。
基本的子模型可能是这样的:
export class User extends Model {
private username: string = null;
constructor () {
super ();
this.processJson ();
}
}
让我们的父Model类做类似的事情:
export class Model {
constructor () {
}
public processJson<T> () {
_.forEach (Object.keys (this), (key: string) => {
console.log (`processing key: ${key}`);
console.log (typeof this[key]);
})
}
}
计划是使用processJson
方法作为单个入口点来获取入站JSON数据,并根据其定义将其处理到我们的子模型中。
这里的问题是,我似乎无法获得在子模型中定义的声明类型,在提供的示例中,typeof this[key]
将返回object
,因为它可以推断出子类型的类型。在此示例null
中分配了值。
我的计划是将其用于更复杂的情况下,在这些情况下,我们可能具有更复杂的对象或具有特殊处理的不同类型,并全部在父模型类的集中位置执行这些操作。
我的问题就是这样,如何知道子模型的属性,以username
NOT string
的形式获取object
示例的声明类型?
这是对生成的基础JavaScript的限制吗?还是我误解了声明的类属性在Typescript中的工作方式?
我知道在将属性声明为:
private username: string = '';
它将为我提供正确的类型,但是在某些情况下,null
可能是有效值,因此我不希望初始化这些值,因为它们是由JSON数据分配的。
答案 0 :(得分:3)
您的代码段假定您在运行时需要打字稿的类型信息。但是,在运行时,所有类型都会被Typescript编译器擦除。它只会发出不带类型注释的普通javascript。
我相信您最好的选择是创建一个装饰器,并用它装饰模型的每个属性-像这样:
class Cylinders extends React.Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
this.state = {
divs: [
{
className: 'hat1'
},
{
className: 'hat2'
},
{
className: 'hat3'
}
]
}
}
componentDidMount = () => {
console.log('mount');
}
handleClick = (item, i) => {
console.log('item', item);
console.log('i', i);
var divCoordinates = ReactDOM.findDOMNode(this).getBoundingClientRect();
console.log(divCoordinates, 'divCoordinates');
// const node = this.myRef.current;
// console.log('node', node);
}
render() {
return (
<section>
<div className="columns is-mobile">
<div className="column">
<h1 className="title has-text-black is-size-2">Cylinders Game</h1>
<button className="has-text-black">Ball container</button>
</div>
</div>
<div className="columns is-mobile">
<div className="colum ballContainer">
<div className="ball"></div>
</div>
</div>
<div className="columns is-mobile">
{this.state.divs.map((item, i) => {
return (
<div className="column">
<div className="columns is-multiline">
<div
onClick={() => this.handleClick(item, i)}
className={item.className}
key={item.name + i}
ref={el => this.containerLine = el}
> {i}
</div>
</div>
</div>
)
})}
</div>
</section>
);
}
}
export default Cylinders;
还要确保启用[typeaheadMinLength]="0"
编译器选项(https://www.typescriptlang.org/docs/handbook/decorators.html#metadata)
它应该允许您通过反射元数据读取装饰属性的类型(例如,此答案中的建议:How to get type data in TypeScript decorator?)。
答案 1 :(得分:0)
您可以使用typeof
,===
严格比较和instanceof
来检查声明的类型
答案 2 :(得分:0)
示例代码:
class Circle {
public kind: string = '';
public radius: number = 0;
}
let objCircle: Circle;
objCircle = {
kind: 'circle1',
radius: 123
} as Circle;
console.log(typeof objCircle.kind === 'string') // true
console.log(typeof objCircle.radius === 'number') // true
console.log(objCircle instanceof Object) // true