编写包含一个options对象并具有默认值的构造函数的干净方法?

时间:2019-01-31 09:40:29

标签: typescript

什么是写一个构造函数的选项对象,并且具有默认一个干净的方式?

我最好尝试低于

export class Client {
    host: string = 'ws://127.0.0.1';
    port: number = 8080;
    logger: (...args: any[]) => void = function() {
        const prefix = "LOG:";
        console.log.call(null, prefix, ...Array.from(arguments))
    };
    maxTime: number = 30000;
    startFromTransactionId: number = 1;
    transactionsCounter: number = 0;
    requestCallbacks: object = {};
    socket: object = {}; 

    constructor(options: {
        host: string, 
        port: number, 
        logger: (...args: any[]) => void , 
        maxTime: number, 
        startFromTransactionId: number
    }) {
        if (options.host) this.host = options.host;
        if (options.port) this.port = options.port;
        if (options.logger) this.logger = options.logger;
        if (options.maxTime) this.maxTime = options.maxTime;
        if (options.startFromTransactionId) this.startFromTransactionId = options.startFromTransactionId;
    }
}

在我的解决方案中,我不喜欢这样:

  • 我为每个属性编写两次类型注释(一次用于选项对象,一次用于新创建对象)
  • 我如果对于每个可选参数
  • 语句

3 个答案:

答案 0 :(得分:1)

在这种情况下,我更喜欢构图:

export class ClientOptions {
  host: string = 'ws:127.0.0.1';
  port: number = 8080;
  ...
}

export class Client {
  public options: ClientOptions;
  public socket: object = {};
  ...

  constructor(public options: ClientOptions = new ClientOptions()) {
    // options is automatically assigned due to `public` keyword in constructor declaration
    ...
  }
}

如果您希望使用this.host而不是this.options.host,则可以执行以下操作:

export class ClientOptions {
  host: string = 'ws:127.0.0.1';
  port: number = 8080;
  ...
}

export class Client extends ClientOptions {      
  public socket: object = {};
  ...

  constructor(options: ClientOptions = new ClientOptions()) {
    Object.assign(this, options);
    ...
  }
}

答案 1 :(得分:0)

也许有帮助:

export class Client {
    public host: string = 'ws://127.0.0.1';
    public port: number = 8080;
    public logger: (...args: any[]) => void = function () {
        const prefix = "LOG:";
        console.log.call(null, prefix, ...Array.from(arguments))
    };
    public maxTime: number = 30000;
    public startFromTransactionId: number = 1;
    public transactionsCounter: number = 0;
    public requestCallbacks: object = {};
    public socket: object = {};

    constructor(options: Client) {
        Object.keys(options).forEach((key) => {
            if (options[key]) {
                this[key] = options[key];
            }
        });
    }
}

如果您不希望这些选项接受客户端的所有属性



export class Base {
    public host: string = 'ws://127.0.0.1';
    public port: number = 8080;
    public logger: (...args: any[]) => void = function () {
        const prefix = "LOG:";
        console.log.call(null, prefix, ...Array.from(arguments))
    };
    public maxTime: number = 30000;
    public startFromTransactionId: number = 1;
    public transactionsCounter: number = 0;
}

export class Client extends Base {
    public requestCallbacks: object = {};
    public socket: object = {};

    constructor(options: Base) {
        super();
        Object.keys(options).forEach((key) => {
            if (options[key]) {
                this[key] = options[key];
            }
        });
    }
}

答案 2 :(得分:0)

我更喜欢这种方式...

interface ConnectOptions {
  dburl:string;
  connectionTimeoutMillis:number;
}

const defaultOptions: ConnectOptions = {
  dburl: "",
  connectionTimeoutMillis: 3000
} 

function connect(options: Partial<ConnectOptions>) {
  const effectiveOptions = Object.assign({}, defaultOptions, options) as ConnectOptions;
  console.log(effectiveOptions.dburl);
  console.log(effectiveOptions.connectionTimeoutMillis);
}

connect({ dburl: "http://mydb/" });
connect({ connectionTimeoutMillis: 1000 });
connect({ dburl: "http://mydb/", connectionTimeoutMillis: 1000 });