Búsqueda de sitios web

¿Cómo establecer parámetros de clase opcionales en Angular 2-Typescript?


Sé que en TypeScript los parámetros opcionales pueden marcarse con un signo de interrogación.

Sin embargo, la única manera que encontré de realmente instanciar la clase es con la palabra clave new.

La cuestión es que, basándose en el tutorial de inicio "héroe" de Angular 2, las clases no se instancian mediante la palabra clave new y, hasta donde entendí, eso lo hace Angular internamente.

Por ejemplo, tengo este código:

modelos/usuarios.ts

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

models/mock-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"
    },        
]

services/usuario.servicio.ts

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

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

vistas/mi-componente.componente.ts

// imports here...

@Component({
   // ...
})

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

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

Respuesta #1

En tu caso, podría ser más conveniente usar una interfaz para User 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 realmente necesitas una clase, entonces la sintaxis para crear instancias de Users en mock-users.ts debería ser un poco diferente. En primer lugar, no hay "campos de clase opcionales" en TypeScript. Cualquier campo puede no estar establecido/'undefined', por lo que no tiene sentido marcar un campo como opcional. Puedes instanciar una clase con la palabra clave new: la desventaja es que necesitas escribir un constructor para establecer los valores de los campos o asignar la instancia a una variable y establecer los campos. Pero no hay nada de malo en usar la palabra clave new, especialmente para objetos de prueba.

También puedes instanciar un objeto con un literal de objeto como lo has hecho en mock-users.ts; necesitas ser más explícito agregando un casting.

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 el cast, el compilador de TypeScript producirá un error. Esto está diseñado para detectar errores. Si quieres saber más sobre las razones (interesantes), aquí hay una discusión detallada relacionada sobre parte del pensamiento detrás de la verificación de tipos:

  • ¿Por qué estoy recibiendo un error "Un literal de objeto solo puede especificar propiedades conocidas"?

  • https://basarat.gitbooks.io/typescript/content/docs/types/freshness.html

Artículos relacionados