I know in Typescript optional parameters can be marked by question mark.
However, the only way I found to actually instantiate the class with new keyword.
The thing is that based on Angular 2's starter "hero" tutorial classes are not instantiated via the new keyword and as far as I understood that's internally done by Angular.
For example I have this code:
models/users.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/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)); } }
Use a question mark to set an optional parameter in a function in TypeScript, e.g. function sum(a: number, b?: number) {} . If set to optional, the parameter can have a type of undefined or the specified type, because unspecified parameters get the value undefined .
TypeScript provides a Optional parameters feature. By using Optional parameters featuers, we can declare some paramters in the function optional, so that client need not required to pass value to optional parameters.
You must tell TypeScript if a property is optional. First, if you don't tell TypeScript that a property is optional, it will expect it to be set. Adding ? to the property name on a type, interface, or class definition will mark that property as optional.
Optional Parameters are parameters that can be specified, but are not required. This allows for functions that are more customizable, without requiring parameters that many users will not need.
In your case, it might be more convenient to use an interface for User instead.
export interface User { id: number; name?: string; // interfaces allow fields to be optional }
I use interfaces when I want to define the 'shape' of an object, classes when I need to add behavior (methods). If all you need is to move data around, I'd use an interface.
If you do need a class, then the syntax for creating instances of Users in mock-users.ts
should be a bit different. Firstly, there's no "optional class fields" in TypeScript. Any field can be not set/'undefined', so it doesn't make sense mark a field optional. You can instantiate a class with the new
keyword - the downside is that you need to write a constructor to set field values or assign the instance to a variable and set fields. But there's nothing wrong with using the new keyword, especially for test objects.
You can also instantiate an object with an object literal as you've done in mock-users.ts
- you need to be more explicit by adding a cast.
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" }, ]
Without the cast, the TypeScript compiler will produce an error. This is by design to catch a mistakes. If you want to know more about the (interesting) reasons, here's a related detailed discussion on some of the thinking behind the type checking:
Why am I getting an error "Object literal may only specify known properties"?
https://basarat.gitbooks.io/typescript/content/docs/types/freshness.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With