打字稿:如何将对象强制转换或分配给属性较少的类型?(从大到小)



我有三个对象(类(,它们如下所示:

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) {}
}

由于类型AB不重叠,因此如果您尝试将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实例的BC创建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"
}

最新更新