我正在尝试使用构造函数和工厂函数来修改Typescript,但是当我通过tsc
运行时,我仍然遇到以下错误。
src/tests/lib/mockNconf.ts(16,14): error TS2322: Type '(conf: Conf) => MockNconf' is not assignable to type 'MockNconfConstructor'.
Type '(conf: Conf) => MockNconf' provides no match for the signature 'new (conf: Conf): MockNconf'.
src/tests/lib/mockNconf.ts(18,12): error TS2350: Only a void function can be called with the 'new' keyword.
我查看了How to define a Typescript constructor and factory function with the same name?,但这只涉及了typescript定义(使用纯javascript实现)。
我的代码是
import * as deepclone from 'lodash.clonedeep';
type Conf = { [key: string]: any };
interface MockNconf {
set(key: string, data: any): void,
get(key: string): any,
clone(): MockNconf
}
interface MockNconfConstructor {
new (conf: Conf): MockNconf;
(conf: Conf): MockNconf;
}
export const MockNconf: MockNconfConstructor = function MockNconf(conf: Conf): MockNconf {
if (!(this instanceof MockNconf)) {
return new MockNconf(conf);
}
this.conf = conf;
};
Object.assign(MockNconf.prototype, {
set: function set(key: string, data: any): void {
if (typeof data === 'undefined') {
if (typeof this.conf[key] !== 'undefined') {
delete this.conf[key];
}
} else {
this.conf[key] = data;
}
},
get: function get(key: string): any {
return this.conf[key];
},
clone: function clone(): MockNconf {
const newConf = deepclone(this.conf);
return new MockNconf(newConf);
}
});
export default MockNconf;
答案 0 :(得分:1)
感谢Titian Cernicova-Dragomir帮助解决问题。它可以在不使用类的情况下完成,但是MockNconf在首次定义时不能被强制转换,而是在构造函数中使用它时以及在导出它时需要进行转换。 / p>
import * as deepclone from 'lodash.clonedeep';
type Conf = { [key: string]: any };
interface MockNconfInterface {
set(key: string, data: any): void,
get(key: string): any,
clone(): MockNconfInterface
}
interface MockNconfConstructor {
new (conf: Conf): MockNconfInterface;
(conf: Conf): MockNconfInterface;
}
const MockNconf = function MockNconf(conf: Conf): MockNconfInterface {
if (!(this instanceof MockNconf)) {
return new (<MockNconfConstructor>MockNconf)(conf);
}
this.conf = conf;
};
Object.assign(MockNconf.prototype, {
set: function set(key: string, data: any): void {
if (typeof data === 'undefined') {
if (typeof this.conf[key] !== 'undefined') {
delete this.conf[key];
}
} else {
this.conf[key] = data;
}
},
get: function get(key: string): any {
return this.conf[key];
},
clone: function clone(): MockNconfInterface {
const newConf = deepclone(this.conf);
return new (<MockNconfConstructor>MockNconf)(newConf);
}
});
export default MockNconf as MockNconfConstructor;
答案 1 :(得分:0)
没有办法在typescript中定义一个既可以作为类又可以作为函数的类/函数。但是,我们可以使用所有必需的方法对常规类进行decalare,并使用类型断言将其导出为MockNconfConstructor
。该类由构造函数表示,因此构造函数将被调用,我们可以使用相同的代码(this instanceof MockNconf
)来检查调用是作为构造函数还是作为常规函数发生的:
class MockNconf {
conf: { [key: string]: any; };
constructor(conf: Conf) {
if (!(this instanceof MockNconf)) {
return new MockNconf(conf);
}
this.conf = conf;
}
set(key: string, data: any): void {
if (typeof data === 'undefined') {
if (typeof this.conf[key] !== 'undefined') {
delete this.conf[key];
}
} else {
this.conf[key] = data;
}
}
get(key: string): any {
return this.conf[key];
}
clone(): MockNconf {
const newConf = deepclone(this.conf);
return new MockNconf(newConf);
}
}
export default MockNconf as MockNconfConstructor;
用法:
import MockNconf from './q48519886';
var foo = MockNconf({ a: 10});
var boo = new MockNconf({a: 10});