在角/TypeScript中创建模型对象的最佳实践是什么:
Object的普通实例)?例如let m: MyModel = { name: 'foo' }new运算符(对象是各自原型的实例)?HttpClient的响应时,普通对象,但为了方便地通过传递属性作为构造函数参数来创建实例,new MyModel('foobar') )本问题的背景
我是TypeScript新手,和其他许多开发人员一样,我来自流行的面向对象语言,比如Java。
我理解的一个核心概念是,TypeScript中的类型注释在运行时不起作用。它们对于编译器和编辑器的自动完成都很重要。基本上,它是带有编译时类型检查的ECMAScript。
当我不知道这一点,并期望TypeScript是某种“客户端Java”时,我发现了这个角度错误报告:https://github.com/angular/angular/issues/20770
人们(不理解类型记录的类型概念)抱怨HttpClient没有将返回的普通对象转换为他们的模型类类型。其他人为这种行为辩护,并指出在JavaScript中不存在运行时类型。
这里出现了我的问题:实际上,在JavaScript中存在运行时类型。您可以使用new操作符创建原型实例,甚至可以使用instanceof操作符检查它们的构造函数。
在TypeScript中,有两种创建实例的方法:
1)使用对象表示法(如它们在角教程中所示):
hero: Hero = {
id: 1,
name: 'Windstorm'
};2)使用new-operator:
hero: Hero = new Hero();目前,我正在做一个项目,在这个项目中,这两个选项是混在一起的。例如,同一类型的模型对象在某些情况下是Object的实例,而在其他情况下是Hero的实例。
我预计这会导致稍后的问题,因为构造函数只在后一种情况下被调用。
我对于规则/最佳实践的想法是将所有模型实例定义为普通对象,并为依赖注入创建的服务、组件等使用构造函数。因此,我根本不会使用new操作符。
然而,我不确定这是否是一个好主意,我也找不到关于它的最佳实践建议。
编辑
对亲密选民重要的注意事项:我不是在这里寻找你的个人观点。我只是在寻找某种官方记载的角度最佳实践,因为我认为这是一个核心设计决策,必须从项目开始就做出,而且这些方法不应该在没有特定原因的情况下随机混合在一起。也许答案只是一个简单的“没有官方建议的决定”。
发布于 2018-08-08 08:58:33
在我看来,如果需要对对象本身执行复杂的操作,应该使用new运算符来创建类的新对象。
如果您只需要访问这些属性,则可以使用对象文本创建一个新对象。
这具有封装、继承等优点,来自Java背景的开发人员可以更好地与之相关。
如果您像下面这样直接分配一个对象,那么您必须显式地在其中设置函数,例如,getName函数。
hero: Hero = {
id: 1,
name: 'Windstorm',
getName: function(){ // returns name }
};但是,通过使用函数Hero定义类getName,然后创建该类的实例,无论创建实例多少次,您都会自动获得该function。
为了更好地理解面向对象的Javascript,您可以遵循以下链接:
关于以下问题,
“人们(不理解类型记录的类型概念)抱怨HttpClient没有将返回的普通对象转换为他们的模型类类型。”
HttpClient只是返回服务器发送的对象,它在JS上将其转换为所需的表单。您始终可以使用它的构造函数将响应映射到所需的模型实例,该构造函数可以定义如下:
constructor(hero){
this.id = hero.id;
this.name = hero.name;
}您可以映射从服务器返回的数组,如下所示:
map(hero => new Hero(hero))发布于 2018-08-08 09:38:09
实际上,JavaScript中有运行时类型。
有点。值可以有某种类型,但是变量和属性没有绑定到它们的类型。也就是说,如果您键入网络请求等。
fetch("someurl").then(res => res.json()) as Promise<IUser>网络请求突然返回用户以外的其他内容,没有什么会失败,因为在运行时类型记录类型不存在。但是,这种行为可以很容易地添加到打字机上:
function isUser(user: any) : user is IUser {
return Number.isInteger(user.id) && typeof user.name === "string";
}它允许您在运行时执行类型检查:
const result = await fetch("someurl");
if(!isUser(result)) throw new Error();
// result is definetly a IUser here我应该使用继承还是不继承?
这是一个偏好问题。我曾经编写过一个大量使用数据库的应用程序,所以我不得不进行大量的序列化/反序列化,而且总是将来自db的响应打包到一个类实例中,这让我非常恼火。因此,对于我的db模型,我开始使用以下模式:
type User = {
name: string;
id: number;
};
const User = {
get(id: number): User { /*...*/ }
changeName(user: User, name: string) { /*..*/ }
};这让我可以写:
const admin: User = User.get(123);我可以简单地在db上做类型转换,而且我都有类型安全性和很好的API。
对于您的usecase来说,这是否是一个好的模式实际上取决于您做了多少序列化/反序列化。
https://stackoverflow.com/questions/51742249
复制相似问题