实现JavaScript选项对象参数模式?

时间:2015-09-18 14:34:57

标签: typescript

JavaScript中有一个常见的模式,即"构造函数"接受可选的选项对象。此外,该选项对象可能只包含调用者希望覆盖的选项。例如:

function Foo(options) {
  this._options = {
    foo: 'bar',
    answer: 42,
    amethod: function(){}
  };
  this._options = Object.assign(this._options, options);
}

let foo1 = new Foo();
foo2._options.foo; // 'bar'
foo1._options.answer; // 42
foo1._options.amethod(); // undefined

let foo2 = new Foo({answer: 0, amethod: function(a) { return a; }});
foo2._options.foo; // 'bar'
foo2._options.answer; // 0
foo2._options.amethod('foo'); // 'foo'

是否可以在Typescript中实现此模式?如果是这样,怎么样?

2 个答案:

答案 0 :(得分:9)

好像你可以使用带有可选成员的接口,并使用已经完成的Object.assign来执行此操作:

interface Options {
  foo?: string;
  answer?: number,
  aMethod?: (a:string) => string;
}

class Foo {
    options: Options;
    constructor(options:Options) {
        this.options = {
            foo: 'bar',
            answer: 42,
            aMethod: function(){}
        };
        Object.assign(this.options, options);
    }
}
var foo1 = new Foo({});
foo1.options.foo; // 'bar'
foo1.options.answer; // 42
foo1.options.aMethod; // function()
var foo2 = new Foo({answer: 0, aMethod: function(a:string) { return a; } );
foo1.options.foo; // 'bar'
foo1.options.answer; // 0
foo1.options.aMethod; // function(a)

TS Playground Example

答案 1 :(得分:0)

在打字稿中

让我输入TS答案。在TS中,您当然可以定义options对象的 type ,但是从TS 3.2开始,您不能在函数参数中分配“部分默认值”(即,当对象的未设置属性为默认为某个值)。

因此,这是使用解构的Web爬网程序功能的真实示例。您也可以使用Object.assign,但是为了确保类型安全,您必须分别定义options的类型接口。

总而言之,唯一的警告是您将不得不两次提及将被赋予默认值的属性。

async downloadPageHTML(url: string, options: {
    cookies?: puppeteer.Cookie[],
    launchOpts?: LaunchOptions,
    pageLoadOpts?: Partial<puppeteer.NavigationOptions>,
    userAgent?: string
    browser?: puppeteer.Browser
} = {}) {
    let {
        pageLoadOpts = {},
        launchOpts = {},
        cookies = [],
        userAgent = getUserAgent(url)
    } = options;
    // ...
}