Suppose you have a very large object defined as a TypeScript interface:
interface AccountInterface {
accountIdentifier?: string;
sid?: string;
idToken?: {
aio?: string;
};
idTokenClaims?: {
aio?: string;
};
}
I would like the object to always have its properties and sub properties. They can either be a string or an empty string:
let account = {
accountIdentifier: "",
sid: "",
idToken: {
aio: "",
},
idTokenClaims: {
aio: "",
},
};
Reading the other questions I thought it would have been possible to do this:
const emptyAccount = {} as AccountInterface
console.log('emptyAccount ', emptyAccount)
console.log('emptyAccount.sid ', emptyAccount.sid)
But this doesn't create an object with all the properties as empty strings as desired.
It would be great if something like this would be possible, so there's no need to duplicate the object in the code, as in one for the interface and one for the object with empty string properties.
Suppose you have a very large object defined as a TypeScript interface:
interface AccountInterface {
accountIdentifier?: string;
sid?: string;
idToken?: {
aio?: string;
};
idTokenClaims?: {
aio?: string;
};
}
I would like the object to always have its properties and sub properties. They can either be a string or an empty string:
let account = {
accountIdentifier: "",
sid: "",
idToken: {
aio: "",
},
idTokenClaims: {
aio: "",
},
};
Reading the other questions I thought it would have been possible to do this:
const emptyAccount = {} as AccountInterface
console.log('emptyAccount ', emptyAccount)
console.log('emptyAccount.sid ', emptyAccount.sid)
But this doesn't create an object with all the properties as empty strings as desired.
It would be great if something like this would be possible, so there's no need to duplicate the object in the code, as in one for the interface and one for the object with empty string properties.
Share edited May 8, 2020 at 14:22 LoremIpsum 4,4281 gold badge16 silver badges17 bronze badges asked May 8, 2020 at 11:59 DarkLite1DarkLite1 14.8k46 gold badges137 silver badges235 bronze badges 3-
1
I don't think there's a "default value that matches interface" feature in typescript and I also don't see any sensible way of providing one automatically. Why would an empty string be default? If the type is
string|number|null
then what would be the default. If the value is optional (which in your case they all are) is the defaultundefined
or the default of the type if it would exist and if so why is it optional then? – apokryfos Commented May 8, 2020 at 12:04 - "Reading the other questions" - which ones? Please link them. – Bergi Commented May 8, 2020 at 12:04
- I'm new to TS so still learning here. Updated the question. – DarkLite1 Commented May 8, 2020 at 12:05
2 Answers
Reset to default 4You can create a class
that implements that interface
, adding the default values, and use that to create your objects. You are still re-writing the same structure elsewhere, but now you only have to do it one time, and you could use the constructor
to initialize your object with different values if you want.
interface AccountInterface {
accountIdentifier?: string;
sid?: string;
idToken?: {
aio?: string;
};
idTokenClaims?: {
aio?: string;
};
}
class Account implements AccountInterface {
accountIdentifier = '';
sid = '';
idToken = { aio: '' };
idTokenClaims = { aio: '' };
}
const emptyAccount = new Account();
Also, as pointed out by @apokryfos, you can also use the class to type objects, so there's no need to define both an instance
and a class
unless you are going to have objects implementing that instance that haven't been created using the class (as those would not have the methods defined in the class).
If you want to avoid using class
and use a function
to do something similar, you totally can:
function createAccount(): AccountInterface {
return {
accountIdentifier = '';
sid = '';
idToken = { aio: '' };
idTokenClaims = { aio: '' };
};
}
const emptyAccount = createAccount();
const emptyAccount = {} as AccountInterface
should create an object. But your AccountInterface only includes properties which may exist but must not (because of the ?). So an empty object pletely matches your AccountInterface.
If you want to have a property with a default value to be included then you will have to declare it in your interface.
interface AccountInterface {
accountIdentifier: string|null // <- will be included in {} as AccountInterface
sid?: string // <- will not be included in {} as AccountInterface
}