Я знаю, что в параметрах
В вашем случае было бы удобнее использовать интерфейс для пользователя.
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 выдаст ошибку. Это по дизайну, чтобы поймать ошибки. Если вы хотите узнать больше о (интересных) причинах, см. Подробное обсуждение некоторых соображений, лежащих в основе проверки типов:
-
благодарит Ronald.может ли вы представить полный пример, пожалуйста (использование)? – dragonmnl 20.04.2016 в 16:32
-
Если весь код, который у вас есть, находится в вопросе, то изменение ключевого слова из класса в интерфейс должно сделать трюк. Я разберу ответ. – Ronald Zarīts 20.04.2016 в 16:35
-
спасибо за дальнейшее объяснение. Я это сделаю. Не могли бы вы объяснить, что мне делать, когда мне нужны как необязательные параметры, так и методы? также, в случае класса с методами, мне нужно создать экземпляр с новым ключом? после этого я приму свой ответ :) – dragonmnl 20.04.2016 в 16:40
-
благодарит за дальнейшие объяснения. как и обещал, я принял ответ. не могли бы вы определить «анонимный объект»? – dragonmnl 20.04.2016 в 17:14
-
Извините, правильный термин - «литерал объекта». Термин «анонимный объект» происходит от языка C #, который мне также очень нравится. Литеральный объект - это просто объект, определенный внутри строки, например, {id: 1, 'name:' John '} – Ronald Zarīts 20.04.2016 в 17:16
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'
});
Я лично предпочитаю этот синтаксис, чтобы избежать многострочной инициализации объекта и скучной вещи для создания интерфейса (так что другой файл совершенно бесполезен, если существует подходящий класс) для каждой модели моего приложения.
Кроме того, не стесняйтесь устанавливать значение по умолчанию в определении вашего класса, даже если это не является обязательным для этого случая.
Последнее важное обстоятельство заключается в том, что вы не теряете методы класса в этом случае (противопоставляя {} casting)