如何在Angular 2-Typescript中设置可选的类参数?

时间:2016-04-20 14:22:13

标签: typescript angular

我知道在Typescript中可选参数可以用问号标记。

但是,我发现实际使用 new 关键字实例化该类的唯一方法。

基于Angular 2的首发英雄"基于Angular 2"英雄"教程类是通过new关键字实例化的,据我所知,这是由Angular内部完成的。

例如我有这段代码:

模型/ users.ts

export class User {
    id: number;
    name: string; // I want this to be optional
}

模型/模拟users.ts

import {User} from './user';

export var USERS: User[] = [
    {
       id: 1
       // no name (I wanted it to be optional for user with id 1)
    },
    {
       id: 2,
       name: "User 2"
    },        
]

服务/ user.service.ts

import {Injectable} from 'angular2/core';
import {USERS} from './../models/mock-users';

@Injectable()
export class UserService {
    getUsers() {
         return Promise.resolve(USERS);
    }
}

视图/我的-component.component.ts

// imports here...

@Component({
   // ...
})

export class MyComponent {
   constructor(private _userService: UserService) { }

   getUsers() {
         this._userService.getUsers().then(users => console.log(users));
   }
}

3 个答案:

答案 0 :(得分:41)

在您的情况下,为用户使用界面可能更方便。

export interface User {
    id: number;
    name?: string; // interfaces allow fields to be optional
}

当我想要定义对象的'形状'时,我需要使用接口,当需要添加行为(方法)时,我会使用类。如果您只需要移动数据,我就会使用一个界面。

如果确实需要一个类,那么在mock-users.ts中创建用户实例的语法应该有点不同。首先,TypeScript中没有“可选类字段”。任何字段都不能设置/'未定义',因此没有意义标记字段可选。您可以使用new关键字实例化一个类 - 缺点是您需要编写构造函数来设置字段值或将实例分配给变量并设置字段。但是使用new关键字没有任何问题,特别是对于测试对象。

您也可以像在mock-users.ts中那样使用对象文字实例化对象 - 您需要通过添加强制转换来更明确。

export var USERS: User[] = [
    <User> { // explicit cast to let the TypeScript compiler know you know what you're doing
       id: 1
       // no name (I wanted it to be optional for user with id 1)
    },
    {
       id: 2,
       name: "User 2"
    },        
]

如果没有强制转换,TypeScript编译器将产生错误。这是设计上的错误。如果你想更多地了解(有趣的)原因,这里有关于类型检查背后的一些思考的相关详细讨论:

答案 1 :(得分:2)

class User {
    constructor(public id: number, public name: string = null) {}
}

var USERS: User[] = [
    new User(1),
    new User(2, 'User 2')
];

console.log(USERS);

JsFiddle

使用构造函数可能会让您的生活更轻松。当您尝试获取用户名时,您将无法获得undefined,并且您将能够在课程中定义功能。唯一的区别是您使用new User(...)而不是仅仅使用对象文字作为类型。

答案 2 :(得分:0)

另一种方法是使用a使用您只需要的属性扩展有效的类型对象(在此示例中省略属性cexport class A { a:number=1; b:number; c:string; d:string; } let validA:A = Object.assign(new A(),{ b:3, d:'Lorem ipsum' });

{{1}}

我个人更喜欢这种语法来避免多行对象初始化以及为我的应用程序的每个模型创建一个接口(所以如果存在相应的类,则另一个文件非常无用)的无聊事物。

此外,请不要犹豫在您的班级定义中设置默认值,即使这种情况不是强制性的。

最后一件重要的事情是,在这种情况下你不会松散类方法(反对{}投射)