Как задать необязательные параметры класса в Angular 2-Typescript?
Я знаю, что в Typescript необязательные параметры могут быть помечены вопросительным знаком.
Однако, единственный способ, который я нашел, чтобы фактически создать экземпляр класса с новым ключевым словом.
Дело в том, что на основе начального урока Angular 2 "hero" классы Не создаются с помощью нового ключевого слова, и, насколько я понял, это делается внутри Angular.
Например, у меня есть это код:
Модели / пользователи.ts
export class User {
id: number;
name: string; // I want this to be optional
}
Модели / макеты-пользователи.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"
},
]
Услуги / пользователь.обслуживание.ts
import {Injectable} from 'angular2/core';
import {USERS} from './../models/mock-users';
@Injectable()
export class UserService {
getUsers() {
return Promise.resolve(USERS);
}
}
Views/my-компонент.деталь.ts
// imports here...
@Component({
// ...
})
export class MyComponent {
constructor(private _userService: UserService) { }
getUsers() {
this._userService.getUsers().then(users => console.log(users));
}
}
3 ответов:
В вашем случае было бы удобнее использовать интерфейс для пользователя.
export interface User { id: number; name?: string; // interfaces allow fields to be optional }Я использую интерфейсы, когда хочу определить "форму" объекта, классы, когда мне нужно добавить поведение (методы). Если все, что вам нужно, это перемещать данные, я бы использовал интерфейс.
Если вам нужен класс, то синтаксис для создания экземпляров пользователей в
mock-users.tsдолжен быть немного другим. Во-первых, в TypeScript нет "необязательных полей класса". Любое поле может быть не задано/ 'undefined', поэтому нет смысла отмечать поле как необязательное. Вы можете создать экземпляр класса с ключевым словом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 выдаст ошибку. Это сделано специально, чтобы поймать ошибку. Если вы хотите узнать больше о (интересных) причинах, вот соответствующее подробное обсуждение некоторых мыслей, стоящих за проверкой типов:
class User { constructor(public id: number, public name: string = null) {} } var USERS: User[] = [ new User(1), new User(2, 'User 2') ]; console.log(USERS);Использование конструктора, вероятно, сделает вашу жизнь намного проще. Вы не получите
undefinedпри попытке получить имя пользователя, и вы сможете определить функции в классе. Единственное отличие состоит в том, что вы используетеnew User(...)вместо того, чтобы просто использовать литерал объекта в качестве типа.
Еще один способ-использовать
Object.assignдля расширения допустимого типизированного объекта с помощью свойства, которое вам только нужно (опуская свойстваaиcв этом примере)export class A { a:number=1; b:number; c:string; d:string; } let validA:A = Object.assign(new A(),{ b:3, d:'Lorem ipsum' });Лично я предпочитаю этот синтаксис, чтобы избежать многострочной инициализации объекта и скучного создания интерфейса (поэтому другой файл совершенно бесполезен, если существует класс coresponding) для каждой модели моего приложения.
Кроме того, не стесняйтесь задавать значение по умолчанию в определении класса, даже если оно не является обязательным для этого дело.
Еще одна важная вещь заключается в том, что в этом случае вы не теряете методы класса (противоположные {} приведению)
Comments