类型转换时的Typescript默认属性

6

有没有一种方法可以将对象强制转换为类类型,以便默认属性值受到尊重?

例如:

class Person {
    name: string = "bob";
    age: number;
    sex: string;
}

var data = {
    "age": 23,
    "sex": "male"
}

var p = <Person>data;

console.log(p.name); // -> undefined

什么是最简单的方法使 p.name 变为 bob?
*编辑
看起来这个方法可行:
var record : Person = Object.assign(new Person(), p);

这是好的做法还是不好的做法?


你应该澄清你的问题。你想要一个类的实例还是在强制转换对象时强制类型?例如,var p:Person = {name="default", ... data} 可以工作并强制类型,但它不是类的实例。为此,你最好使用一个带有初始化器的类构造函数。请参阅:https://dev59.com/A2Yq5IYBdhLWcg3w2UMU#37682352 - Meirion Hughes
我想要一个类的实例,其中包含从JSON中获取的数据。 - Guerrilla
2个回答

4
最简单的获得该类实例的方法是使用构造函数初始化器,并将默认值作为可选项字段:
class Person {
  name?: string = "bob";
  age: number;
  sex: string;
  constructor(opt: Person) {
    Object.assign(this, opt);
  }
} 

或者在初始化方面明确哪些是可选的,哪些是必需的。
class Person {
  name: string = "bob";
  age: number;
  sex: string;
  constructor(opt: { name?: string, age: number; sex: string; }) {
    Object.assign(this, opt);
  }
}

或者,如果您不在意传递的内容,只需将初始化字段全部设置为可选项:
class Person {
  name: string = "bob";
  age: number;
  sex: string;
  constructor(opt?: Partial<Person>) {
    Object.assign(this, opt);
  }
}

如果您不关心它是否是该类的实例,但是希望强制执行字段和类型,则避免使用强制转换,而是直接显式设置变量的类型:

var data = {
    "age": 23,
    "sex": "male"
}

var p1:Person = {name:"bob", ... data}; // or
var p2:Person = {new Person(), ... data};

谢谢。为什么默认字段必须是可选的? - Guerrilla
这意味着您不必通过初始化器传递它们:例如:new Person({age:20, sex:"male"}) - Meirion Hughes

1

使用类型断言(类型转换)无法实现此操作;它们在编译时进行评估,而默认值则在运行时解析。

它们是完全不同的阶段。


有什么方法可以做到这一点?有没有实例化对象的方法,然后合并属性,以便默认值存在? - Guerrilla
是的,你可以将它们与你的实例一起展开{...p, ...overrides}。或者,如果你想要默认值:{...defaults, ...p}。无论如何,你都需要在某个时候使用new - Eliran Malka
我看了一下关于spread的页面,但是我没有看到任何明显的方法可以将其应用于合并对象。不过,我通过使用Object.assign(new Person(), p)使其正常工作了,但我不确定像这样使用默认属性来初始化所有对象是否是一个好习惯。 - Guerrilla
@Guerrilla - 听起来很棒。如果它符合您的需求,您应该将其发布为答案。 - Eliran Malka

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接