如何init一个新的类在TS以这样的方式(在c#的例子,以显示我想要的):
// ... some code before
return new MyClass { Field1 = "ASD", Field2 = "QWE" };
// ... some code after
如何init一个新的类在TS以这样的方式(在c#的例子,以显示我想要的):
// ... some code before
return new MyClass { Field1 = "ASD", Field2 = "QWE" };
// ... some code after
当前回答
这是另一个解决方案:
return {
Field1 : "ASD",
Field2 : "QWE"
} as myClass;
其他回答
type ExcludeMethods<T> = Pick<T, { [K in keyof T]: T[K] extends Function ? never : K }[keyof T]>;
class Person{
name: string = "N/A";
age: number = 0;
gender?: "male" | "female"
constructor(init?:ExcludeMethods<Person>){
Object.assign(this, init);
}
Describe(){return `${this.name} ${this.age} ${this.gender ?? ""}` }
}
var p1 = new Person();
var p2 = new Person({
name: "John",
age: 20
});
var p3 = new Person({
name: "Mary",
age: 25,
gender: "female"
});
console.log(p1.Describe()) // N/A 0
console.log(p2.Describe()) // John 20
console.log(p3.Describe()) // Mary 25 female
可以影响类类型中强制转换的匿名对象。 奖励:在visual studio中,你可以这样受益于智能感知:)
var anInstance: AClass = <AClass> {
Property1: "Value",
Property2: "Value",
PropertyBoolean: true,
PropertyNumber: 1
};
编辑:
警告:如果类有方法,类的实例将得不到它们。如果AClass有构造函数,它将不会被执行。如果使用instanceof AClass,则会得到false。
总之,应该使用接口而不是类。 最常见的用途是声明为普通旧对象的域模型。 实际上,对于域模型,您应该更好地使用接口而不是类。接口在编译时用于类型检查,与类不同,接口在编译期间被完全删除。
interface IModel {
Property1: string;
Property2: string;
PropertyBoolean: boolean;
PropertyNumber: number;
}
var anObject: IModel = {
Property1: "Value",
Property2: "Value",
PropertyBoolean: true,
PropertyNumber: 1
};
这是我找到的最好的解决办法。
声明一个可以用作装饰器的函数。我称之为自动反射
export function AutoReflect<T extends { new(...args: any[]): {} }>(
constructor: T
) {
return class extends constructor {
constructor(...args: any[]) {
super(args)
if (typeof args[0] === 'object') {
Object.assign(this, args[0]);
}
}
};
}
这样做的目的是在构造函数中期望一个对象,并将成员分配给类实例。 在类声明中使用这个
interface IPerson {
name: string;
age: number;
}
@AutoReflect
class Person implements IPerson {
name: string;
number: number;
constructor(model?: Partial<IPerson>){}
}
在模型的构造函数中,您可以使模型成为可选的,并且在使用Partial时,您可以在不设置所有属性值的情况下新建实例
new Person({
name: 'Santa'
});
这个方法创建了一个您想要的类的新实例,并且对它有c#对象初始化的感觉。
在某些情况下,使用Object.create可能是可以接受的。如果您需要向后兼容或想要滚动自己的初始化函数,Mozilla引用包含一个polyfill。
应用于你的例子:
Object.create(Person.prototype, {
'Field1': { value: 'ASD' },
'Field2': { value: 'QWE' }
});
有用的场景
单元测试 内联声明
在我的案例中,我发现这在单元测试中很有用,原因有二:
在测试期望时,我经常希望创建一个苗条的对象作为期望 单元测试框架(如Jasmine)可能会比较对象原型(__proto__)并使测试失败。例如:
var actual = new MyClass();
actual.field1 = "ASD";
expect({ field1: "ASD" }).toEqual(actual); // fails
单元测试失败的输出不会产生关于不匹配的线索。
在单元测试中,我可以选择我支持的浏览器
最后,http://typescript.codeplex.com/workitem/334上提出的解决方案不支持内联json风格的声明。例如,以下代码不能编译:
var o = {
m: MyClass: { Field1:"ASD" }
};
最简单的方法是使用类型强制转换。
return <MyClass>{ Field1: "ASD", Field2: "QWE" };