Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeScript interface default value on string property

Tags:

typescript

I have an interface that looks like this

export interface IAppSection {
  key: string;
  order: number;
  header: string;
  content: string;
  modifiedAt: string;
  modifiedByEmployeeId: number;
  change: 'added' | 'removed' | 'updated' | 'none';
}

What I'd like to do is have change default as none when the object this interface relates to is stored.

I have tried change: 'added' | 'removed' | 'updated' | 'none' = 'none' but this does not work.

I am sure I am doing something wrong here and would really appreciate some feedback on how I can achieve this.

like image 769
Harry Blue Avatar asked Jul 05 '18 10:07

Harry Blue


People also ask

Can TypeScript interface have default value?

In TypeScript, interfaces represent the shape of an object. They support many different features like optional parameters but unfortunately do not support setting up default values.

How do I declare a default value in TypeScript?

To set a default value for a function parameter, use an equal sign right after the parameter name, e.g. function multiply(num: number, by = 10) {} . If a value for the parameter is not provided, the argument will be replaced with the default value.

How do you make properties optional in interface TypeScript?

Use the Partial utility type to make all of the properties in a type optional, e.g. const emp: Partial<Employee> = {}; . The Partial utility type constructs a new type with all properties of the provided type set to optional. Copied!

How do I inherit an interface in TypeScript?

Interfaces and Inheritance An interface can be extended by other interfaces. In other words, an interface can inherit from other interface. Typescript allows an interface to inherit from multiple interfaces. Use the extends keyword to implement inheritance among interfaces.


1 Answers

You can't do this with interfaces. Interfaces are completely erased at runtime and can't 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'
})
like image 197
Titian Cernicova-Dragomir Avatar answered Sep 22 '22 13:09

Titian Cernicova-Dragomir