use*_*143 12 constructor copy-constructor typescript
我在 type script 上有一堂课:
export class Child {
name:string;
age:number;
}
Run Code Online (Sandbox Code Playgroud)
我想强制类实例只具有类声明所具有的属性。
例如,如果我从 firebase 获取一个对象:
myFirebaseService.getChild(id).then(function(child){
var currentChild = new Child(child);
})
Run Code Online (Sandbox Code Playgroud)
所以当对象是:{name:"ben", color:"db"} 时,我希望结果是:
currentChild = {"name":"ben"}
Run Code Online (Sandbox Code Playgroud)
因为“颜色”不是“孩子”的领域。
我试过这个:
export class Child {
name:string;
age:number;
constructor(tempChild:Child = null) {
if (tempChild){
for (var prop in tempChild) {
this[prop] = tempChild[prop];
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
但它没有帮助。“currentChild”获取所有字段并将它们附加到类实例。
(当然,我可以使用以下代码:
export class Child {
name:string;
age:number;
constructor(tempChild:Child = null) {
if (tempChild){
this.nam = tempChild.name;
this.age =tempChild.ageÏ;
}
}
}
Run Code Online (Sandbox Code Playgroud)
,但我的真理课有很多字段,我想要短代码)
ego*_*xyz 11
我们想要的是:
解决方案:
class Animal {
name: string = 'default value';
group: string = 'default value';
constructor(data: Partial<Animal> = {}) {
Object.assign(this, data)
}
echo() {
return `My name is ${this.name}, I'm from: ${this.group}`;
}
}
class Dog extends Animal {
echo() {
return super.echo() + ' from Dog class';
}
}
const dog = new Dog({name: 'Teddy'});
console.log(dog.echo());
Run Code Online (Sandbox Code Playgroud)
Animal - 根类
Dog - 嵌套类
所有作品都没有打字稿错误
在我看来,从任意对象构建类实例的最干净的方法是使用解构。您仍然可以对所有字段进行分配,但是您可以(非常干净地)控制该字段不存在时会发生的情况,以及将分配给类字段的字段:
export class Child {
name:string
age:number
constructor({name = 'default name', age = 0} = {}) {
this.name = name
this.age = age
}
}
Run Code Online (Sandbox Code Playgroud)
现在,这可以让您从Objects 或anys 或任何部分对象文字创建实例,但是当使用文字时,它不会让您添加额外的东西,这似乎是您所需要的:
const c0 = new Child({} as any /* as Object works as well */)
const c1 = new Child({}) // Literal, will be using defaults
const c2 = new Child() // No argument, using defaults only
const c3 = new Child({ name: 'a', age: 1 })
const c4 = new Child({ name: 'b', foo: 'bar'}) // error with foo
Run Code Online (Sandbox Code Playgroud)
生成的 js 将检查您需要手动检查的所有内容:
define(["require", "exports"], function (require, exports) {
"use strict";
var Child = (function () {
function Child(_a) {
var _b = _a === void 0 ? {} : _a, _c = _b.name, name = _c === void 0 ? 'default name' : _c, _d = _b.age, age = _d === void 0 ? 0 : _d;
this.name = name;
this.age = age;
}
return Child;
}());
exports.Child = Child;
});
Run Code Online (Sandbox Code Playgroud)
尝试在操场上看看由此生成了什么!
这里没有太多选择,因为您在构造函数之前在类中进行的成员定义不会被转换为 javascript,编译器会将它们排除在外:
class Child {
name: string;
age: number;
constructor() {
this.name = "name";
}
}
Run Code Online (Sandbox Code Playgroud)
编译成:
var Child = (function () {
function Child() {
this.name = "name";
}
return Child;
}());
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,该name成员是那里唯一的成员,甚至仅在分配时才使用。
因为您在运行时需要成员的名称,所以您需要将它们放在一边,例如在数组中:
class Child {
private static MEMBERS = ["name", "age"];
name: string;
age: number;
constructor(tempChild: Child = null) {
if (tempChild) {
for (var prop in tempChild) {
if (Child.MEMBERS.indexOf(props) >= 0) {
this[prop] = tempChild[prop];
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这使用起来不太舒服,所以你可以使用装饰器。
例如:
function member(cls: any, name: string) {
if (!cls.constructor.MEMBERS) {
cls.constructor.MEMBERS = [];
}
cls.constructor.MEMBERS.push(name);
}
function isMember(cls: any, name: string): boolean {
return cls.MEMBERS[name] != null;
}
class Child {
@member
name: string;
@member
age: number;
constructor(tempChild: Child = null) {
if (tempChild) {
for (var prop in tempChild) {
if (isMember(Child, prop)) {
this[prop] = tempChild[prop];
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
(操场上的代码)
它没有经过测试,所以我不确定它是否有效,但如果您决定这样做,那么它就是您所需要的大部分内容。
| 归档时间: |
|
| 查看次数: |
11613 次 |
| 最近记录: |