Подтвердить что ты не робот

Как установить дополнительные параметры класса в Angular 2- Typescript?

Я знаю, что в Typescript необязательных параметры могут быть отмечены знаком вопросительного знака.

Однако, единственный способ найти экземпляр класса с ключевым словом new.

Дело в том, что на основе классов Angular 2 стартера "герой" учебники не, созданных с помощью нового ключевого слова, и насколько я понял, что внутренне сделано 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));
   }
}
4b9b3361

Ответ 1

В вашем случае было бы удобнее использовать интерфейс для пользователя.

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

Я использую интерфейсы, когда хочу определить "фигуру" объекта, классы, когда мне нужно добавить поведение (методы). Если вам нужно только перемещать данные, я бы использовал интерфейс.

Если вам нужен класс, то синтаксис для создания экземпляров Users в 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 выдаст ошибку. Это по дизайну, чтобы поймать ошибки. Если вы хотите узнать больше о (интересных) причинах, здесь приведено подробное обсуждение некоторых соображений, лежащих в основе проверки типов:

Ответ 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(...) вместо того, чтобы просто использовать литерал объекта как тип.

Ответ 3

Другим способом является использование 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'
});

Я лично предпочитаю этот синтаксис, чтобы избежать многострочной инициализации объекта и скучной вещи для создания интерфейса (так что другой файл совершенно бесполезен, если существует подходящий класс) для каждой модели моего приложения.

Кроме того, не стесняйтесь устанавливать значение по умолчанию в определении вашего класса, даже если оно не является обязательным для этого случая.

Последнее важное обстоятельство заключается в том, что вы не теряете методы класса в этом случае (противопоставляя {} casting)