Yes, easily, and you don't need to add a class constructor.
export class Profile extends ServerData {
name: string;
email: string;
age: number = 0;
}
The ability to define default values is one of the main things that differentiates a class from an interface.
For this to work you need to call new Profile() somewhere in your code, otherwise a class instance won't be created and you won't have defaults set, because the above TypeScript will compile to the following JavaScript:
var Profile = /** @class */ (function () {
function Profile() {
this.age = 0;
}
return Profile;
}());
So just using it for type assertion at compile-time isn't sufficient to set a default at run-time.
See it in action in the TypeScript Playground.
Answer from msanford on Stack OverflowYes, easily, and you don't need to add a class constructor.
export class Profile extends ServerData {
name: string;
email: string;
age: number = 0;
}
The ability to define default values is one of the main things that differentiates a class from an interface.
For this to work you need to call new Profile() somewhere in your code, otherwise a class instance won't be created and you won't have defaults set, because the above TypeScript will compile to the following JavaScript:
var Profile = /** @class */ (function () {
function Profile() {
this.age = 0;
}
return Profile;
}());
So just using it for type assertion at compile-time isn't sufficient to set a default at run-time.
See it in action in the TypeScript Playground.
The reason you're seeing overwriting properties is due to type erasure in TypeScript. TypeScript has no idea what types of objects are assigned to its variables during runtime. This would seem somewhat strange to you if you're coming not from a java / c# background.
Because in the end , it's just JavaScript. And JavaScript doesn't enforce strict type checking.
In order to ensure that your profile objects always have an age property, you could create your own objects then copy over the values you get from the response. This is the usual approach when it comes to wire format to domain object mapping.
To do this first create your domain model, a Profile class with a default age property in this case.
export class Profile {
constructor(
public name: string,
public email: string,
public age: number = 0) { }
}
Then map your response to the domain model.
this.resultsManagerService.getResults(this.config.request.action, this.pagingAndSorting, this.args).subscribe(
results => {
let res = (results as Profile[]).map((profile) => new Profile(profile.name, profile.email, profile.age));
this.results = this.results.concat(res);
});
I have a class like this but I want to initialize a default value for Id and email when there is no data. How do I do that? As you see, I want to set the default value if I pass new Recipient ()
const user = this.options.find(x=>x.id == 1);
return user? new Recipient (id:user.id, email:user.email): new Recipient ();
export class Recipient {
id: number;
email?: string;
constructor(data?: Partial<Recipient>) {
Object.assign(this, data);
}
}=======================Update======================
eventually I chose one of two options
export class Recipient {
id: number;
email?: string;
constructor(data?: Partial<Recipient>) {
this.id = data?.id || 0;
this.email = data?.email || null;
}
}
export class Recipient {
id: number;
email?: string;
constructor(data?: Partial<Recipient>) {
Object.assign(this,{id:0, email :null}, data);
}
}
How to set default class property value in TypeScript declaration file?
Add support for prototype-based property default values
Init class instance in one line and respect default values with DRY principle
angular - TypeScript Default Value for property - Stack Overflow
Try removing declare from your class definition. By using declare it will define a class type. The type is only defined, and shouldn't have an implementation.
class Foo extends Bar {
foo: number = 60
}
Your program attempts to perform two mutually contradictory tasks.
- It tries to declare that a class exists but is actually implemented elsewhere/otherwise.
- It tries to define that implementation.
You need to determine which of these tasks you wish to perform and adjust your program accordingly by removing either the initializer or the declare modifier.
You can have a class for User instead of an interface, and in the getter do something like:
class User {
private _name: string;
...
get name() {
return this._name || "";
}
}
or even assign an empty string to this._name in the constructor.
If you prefer to use an interface you can have a function that does that:
function normalizeUser(user: User) {
return Object.assign({ name: "" }, user);
}
Edit
Yes, here's how to set the default value in the ctor:
class User {
private static DEFAULT_NAME = "";
public name: string;
...
constructor() {
this.name = User.DEFAULT_NAME;
}
}
As for the get name() part, it's an accessor, so if you use it then:
let a = new User();
console.log(a.name);
More on accessors.
Also you can use this shorthand:
class User {
constructor(public id: number = -1,
public name: string = '',
public logoUrl: File = 'defaultLogo.png' ,
public emailUserName: string = ''
public emailPassword: string = '') {}
}
So I usually create an object for a functionality in my app. But how should I give default values to variables until they are declared? It's a little complicated so TS can't infere it by itself.
I am a beginner so thanks for any help :)
export const DOM = {
root: document.documentElement,
html: document.documentElement,
body: document.body,
img: /* what am I supposed to put here */,
/* this is inited from another function */
async init() {
this.createImgContainer();
},
createImg() {
this.img = document.body.firstElementChild as HTMLImageElement;
};
}Actually, there appears to now be a simple way. The following code works in TypeScript 1.5:
function sayName({ first, last = 'Smith' }: {first: string; last?: string }): void {
const name = first + ' ' + last;
console.log(name);
}
sayName({ first: 'Bob' });
The trick is to first put in brackets what keys you want to pick from the argument object, with key=value for any defaults. Follow that with the : and a type declaration.
This is a little different than what you were trying to do, because instead of having an intact params object, you have instead have dereferenced variables.
If you want to make it optional to pass anything to the function, add a ? for all keys in the type, and add a default of ={} after the type declaration:
function sayName({first='Bob',last='Smith'}: {first?: string; last?: string}={}){
var name = first + " " + last;
alert(name);
}
sayName();
Typescript supports default parameters now:
https://www.typescriptlang.org/docs/handbook/functions.html
Also, adding a default value allows you to omit the type declaration, because it can be inferred from the default value:
function sayName(firstName: string, lastName = "Smith") {
const name = firstName + ' ' + lastName;
alert(name);
}
sayName('Bob');
You cannot add default values directly to a type declaration.
You can do something like this instead:
// Declare the type
export type SomeType = {
typename: string;
strength: number;
radius: number;
some_func: Function;
some_other_stat: number;
}
// Create an object with all the necessary defaults
const defaultSomeType = {
some_other_stat: 8
}
// Inject default values into your variable using spread operator.
const someTypeVariable: SomeType = {
...defaultSomeType,
typename: 'name',
strength: 5,
radius: 2,
some_func: () => {}
}
Type does not exist in runtime, so a default value makes no sense. If you want to have a default default, you must use something that exists in runtime, such as a class or a factory function
Can I tell the interface to default the properties I don't supply to null? What would let me do this
No. You cannot provide default values for interfaces or type aliases as they are compile time only and default values need runtime support
Alternative
But values that are not specified default to undefined in JavaScript runtimes. So you can mark them as optional:
interface IX {
a: string,
b?: any,
c?: AnotherType
}
And now when you create it you only need to provide a:
let x: IX = {
a: 'abc'
};
You can provide the values as needed:
x.a = 'xyz'
x.b = 123
x.c = new AnotherType()
You can't set default values in an interface, but you can accomplish what you want to do by using optional properties:
Simply change the interface to:
interface IX {
a: string,
b?: any,
c?: AnotherType
}
You can then do:
let x: IX = {
a: 'abc'
}
And use your init function to assign default values to x.b and x.c if those properies are not set.