paso - parametros por referencia typescript
¿Cómo establecer parámetros de clase opcionales en Angular 2-Typescript? (3)
Sé que en Typescript los parámetros opcionales se pueden marcar con un signo de interrogación .
Sin embargo, la única forma que encontré para crear una instancia de la clase con una nueva palabra clave.
La cuestión es que las clases tutoriales de "héroe" de inicio de Angular 2 no se crean a través de la nueva palabra clave y, por lo que he entendido, Angular las realiza internamente.
Por ejemplo tengo este código:
modelos / usuarios.ts
export class User {
id: number;
name: string; // I want this to be optional
}
modelos / simulacros-usuarios.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"
},
]
servicios / user.service.ts
import {Injectable} from ''angular2/core'';
import {USERS} from ''./../models/mock-users'';
@Injectable()
export class UserService {
getUsers() {
return Promise.resolve(USERS);
}
}
views / my-component.component.ts
// imports here...
@Component({
// ...
})
export class MyComponent {
constructor(private _userService: UserService) { }
getUsers() {
this._userService.getUsers().then(users => console.log(users));
}
}
En su caso, podría ser más conveniente utilizar una interfaz para Usuario en su lugar.
export interface User {
id: number;
name?: string; // interfaces allow fields to be optional
}
Uso interfaces cuando quiero definir la ''forma'' de un objeto, clases cuando necesito agregar comportamiento (métodos). Si todo lo que necesitas es mover datos, usaría una interfaz.
Si necesita una clase, entonces la sintaxis para crear instancias de Usuarios en mock-users.ts
debería ser un poco diferente. En primer lugar, no hay "campos de clase opcionales" en TypeScript. Cualquier campo no se puede establecer / ''indefinido'', por lo que no tiene sentido marcar un campo como opcional. Puede crear una instancia de una clase con la new
palabra clave; el inconveniente es que necesita escribir un constructor para establecer valores de campo o asignar la instancia a una variable y establecer campos. Pero no hay nada de malo en usar la nueva palabra clave, especialmente para los objetos de prueba.
También puede crear una instancia de un objeto con un objeto literal como lo ha hecho en mock-users.ts
; debe ser más explícito agregando una 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"
},
]
Sin la conversión, el compilador de TypeScript producirá un error. Esto es por diseño para atrapar un error. Si desea saber más sobre las razones (interesantes), aquí hay una discusión detallada relacionada con algunas de las ideas detrás de la verificación de tipo:
Otra forma es usar Object.assign
para extender un objeto escrito válido con la propiedad que solo necesita (omitiendo la propiedad a
y c
en este ejemplo)
export class A {
a:number=1;
b:number;
c:string;
d:string;
}
let validA:A = Object.assign(new A(),{
b:3,
d:''Lorem ipsum''
});
Personalmente, prefiero esta sintaxis para evitar la inicialización de objetos multilínea y lo aburrido para crear una interfaz (por lo que otro archivo es bastante inútil si existe una clase correspondiente) para cada modelo de mi aplicación.
Además, no dude en establecer un valor predeterminado en su definición de clase, incluso si no es obligatorio para este caso.
Una última cosa importante es que no pierdes los métodos de clase en este caso (oponiéndote a la {} casting)
class User {
constructor(public id: number, public name: string = null) {}
}
var USERS: User[] = [
new User(1),
new User(2, ''User 2'')
];
console.log(USERS);
Usar un constructor probablemente hará tu vida mucho más fácil. No obtendrá undefined
cuando intente obtener el nombre de un usuario y podrá definir funciones en la clase. La única diferencia es que usaría un new User(...)
lugar de usar un objeto literal como tipo.