简体   繁体   English

字符串属性上的 TypeScript 接口默认值

[英]TypeScript interface default value on string property

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.我想要做的是在存储与此接口相关的对象时将默认changenone

I have tried change: 'added' | 'removed' | 'updated' | 'none' = 'none'我试过change: 'added' | 'removed' | 'updated' | 'none' = 'none' change: 'added' | 'removed' | 'updated' | 'none' = 'none' change: 'added' | 'removed' | 'updated' | 'none' = 'none' but this does not work. change: 'added' | 'removed' | 'updated' | 'none' = 'none'但这不起作用。

I am sure I am doing something wrong here and would really appreciate some feedback on how I can achieve this.我确信我在这里做错了,非常感谢一些关于我如何实现这一目标的反馈。

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'
})

You can't 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 接口默认值

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另一种处理方法是将所有IAppSection值标记为需要,然后使用工厂方法创建IAppSection对象,在工厂方法中,您可以确保满足所有不变量并为每个实例为可选参数分配默认值

    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'
       }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM