TypeScript interface default value on string property
TypeScript interface default value on string property
You cant do this with interfaces. Interfaces are completely erased at runtime and cant impact runtime behaviour; this is by design. You can create a class instead and assign a default value to the field, or you can create a function that will assign the defaults.
We could even construct a function that helps us create such functions with defaults:
interface IAppSection {
key: string;
order: number;
header: string;
content: string;
modifiedAt: string;
modifiedByEmployeeId: number;
change: added | removed | updated | none;
}
function withDefaults<T>() {
return function <TDefaults extends Partial<T>>(defs: TDefaults) {
return function (p: Pick<T, Exclude<keyof T, keyof TDefaults>> & Partial<TDefaults>) :T {
let result: any = p;
for (let k of Object.keys(defs)) {
result[k] = result[k] || defs[k];
}
return result;
}
}
}
const appSection = withDefaults<IAppSection>()({
change: none
})
You cant set the default value in the interface, only in the implementation.
But by default they are undefined which is mostly just fine.
For the real implementation your string union looks good.
See also:
Typescript interface default values
TypeScript interface default value on string property
Another way to deal with is marking all IAppSection values as required, and then use factory methods to create the IAppSection objects, inside the factory method you can ensure that all invariants are meet and assign default values for the optional arguments, per instance.
TypeScript interface default value on string property
const createAppSection = (
key: string,
order: number,
header: string,
content: string,
modifiedAt: string,
modifiedByEmployeeId: number,
change?: added | removed | updated | none;
) : IAppSection => {
// perform invariants validations
if(!key){
throw Error(key required);
}
return {
key, order, content, modifiedAt, modifiedByEmployeeId,
change: change || none
}
}