我有三个对象(类(,它们如下所示:
class A {
public value1: string;
public value2: string;
public value3: string;
public value4: string;
public value5: string;
}
class B {
public value1: string;
public value2: string;
}
class C {
public value3: string;
public value4: string;
public value5: string;
}
现在我有一个 JSON,如下所示:
{
"value1": "ONE",
"value2": "TWO",
"value3": "THREE",
"value4": "FOUR",
"value5": "FIVE"
}
我想知道是否有任何干净的方法可以将类A
投射到类B
和类C
?
我尝试了这种方法,但是在map
之后,类B
具有A
中的所有 5 个属性,而不是B
上定义的 2 个属性。
class B {
public value1: string;
public value2: string;
constructor(item: A) {
Object.assign(this, item);
}
}
let arr1: A[{"value1":"ONE","value2":"TWO","value3":"THREE","value4":"FOUR","value5":"FIVE"}];
let arr2 = arr1.map(item => new B(item));
Result: B -> {"value1":"ONE","value2":"TWO","value3":"THREE","value4":"FOUR","value5":"FIVE"}]
instead of
B -> {"value1":"ONE","value2":"TWO"}]
您要求打字稿修改值
Typescript 不运行您的代码,仅编译和检查类型安全性
你可以做的是:将空属性定义为 B 类,并检查键
class A {
public value1: string
public value2: string
public value3: string
public value4: string
public value5: string
}
class B {
public value1: string = undefined // <-- define
public value2: string = undefined // <-- define
constructor (item: A) {
const keys = Object.keys(item) // get items keys
const thisKeys = Object.keys(this) // get this class keys
const limitedItem = keys.reduce((newObj, key) => { // combine same keys
if (thisKeys.includes(key)) {
newObj[key] = item[key]
}
return newObj
}, {})
Object.assign(this, limitedItem) // asign to this class
}
}
const arr1 = [{ value1: '1', value2: '2', value3: '3', value4: '4', value5: '5' }]
let arr2 = arr1.map(item => new B(item))
console.log('arr2', arr2)
// arr2 [ B { value1: '1', value2: '2' } ]
来自 TypeScript Deep Dive
类型断言与强制转换
之所以不称为"类型强制转换",是因为强制转换通常意味着某种运行时支持。但是,类型断言纯粹是一种编译时构造,也是向编译器提供有关如何分析代码的提示的一种方式。
类型断言告诉 Typescript 编译器,您已经知道可以将值安全地视为另一种类型,即使无法通过静态分析对其进行验证。
类型断言示例
class A {
constructor(public val1: string, public val2: string, public val3: string,
public val4: string, public val5: string) {}
}
class B {
constructor(public num1: number, public num2: number) {}
}
由于类型A
和B
不重叠,因此如果您尝试将A
实例分配给B
,Typescript 编译器将发出警告。
let a = new A('a', 'b', 'c', 'd', 'e');
let b: B = a; // Error: Type 'A' is missing the following properties from type 'B': num1, num2
使用类型断言,您可以告诉编译器忽略不匹配的类型,在这种情况下这是一个坏主意。
let a = new A('a', 'b', 'c', 'd', 'e');
let b: B = <any> a;
let b2: B = a as any;
您要问的是,如何限制在复制属性多于目标类的类的实例时分配的属性。在您的示例中,一种简单的方法是为接受A
实例的B
和C
创建static
工厂函数(即专用构造函数(,如下所示。
使用静态工厂函数的示例
class A {
constructor(public val1: string, public val2: string, public val3: string,
public val4: string, public val5: string) {}
}
class B {
constructor(public val1: string, public val2: string) {}
static constructFromA(a: A): B {
return new B(a.val1, a.val2);
}
}
class C {
constructor(public val3: string, public val4: string, public val5: string) {}
static constructFromA(a: A): C {
return new C(a.val3, a.val4, a.val5);
}
}
let a = new A('a', 'b', 'c', 'd', 'e');
let b = B.constructFromA(a);
let c = C.constructFromA(a);
console.log(JSON.stringify(b, null, 2));
console.log(JSON.stringify(c, null, 2));
输出
// New B from A
{
"val1": "a",
"val2": "b"
}
// New C from A
{
"val3": "c",
"val4": "d",
"val5": "e"
}