JavaScript中有一种常见的模式,其中“构造函数”接受一个可选的options对象。此外,该选项对象可能仅包含调用者希望覆盖的选项。例如:
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中实现此模式?如果是这样,如何?
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)
interface Options {
foo?: string;
answer?: number,
aMethod?: (a:string) => string;
}
class Foo {
options: Options;
constructor({
foo = 'bar',
answer = 42,
aMethod = undefined
}: Options = {}) {
this.options = { foo, answer, aMethod };
}
}
var foo1 = new Foo();
console.log("foo1: foo", foo1.options.foo); // 'bar'
console.log("foo1: answer", foo1.options.answer); // 42
console.log("foo1: aMethod", foo1.options.aMethod); // function()
var foo2 = new Foo({answer: 0, aMethod: (a:string) => { return a; } );
console.log("foo2: foo", foo2.options.foo); // 'bar'
console.log("foo2: answer", foo2.options.answer); // 0
console.log("foo2: aMethod", foo2.options.aMethod); // function(a)
进一步说明:http://simonsmith.io/destructuring-objects-as-function-parameters-in-es6/
因此,这是使用解构的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;
// ...
}
type Options = {
ID string; // Required
Nickname? string; // Optional
}
const defaultOptions: Partial<Options> = {
Nickname: "Optional me",
};
const doStuff(options: Options) {
const opts: Options = { ...defaultOptions, ...options };
console.log(chompString(opts.ID));
console.log(chompString(opts.Nickname as string));
};
// Usage
doStuff({ ID: "CantSkipThis" });