我有以下javascript函数,它返回一个包含对象参数中给出的其他方法的函数 我认为代码比解释更容易理解:
var scopeFunction = (object) => {
// create main function if it doesn't exist
if (!object.main) object.main = function(){
alert("No main function for this scopeFunction");
};
// add all object keys to the main function that will be return
_.each(object, function(d,i){ object.main[i] = d; });
// return main function
return object.main;
};
我想在typescript中正确定义这段代码,这就是我所做的,但是当我尝试访问返回的函数对象的键时,原子打字稿(我测试它的地方)会抛出错误。 这就是我当前代码的外观:
// TYPES
namespace ScopeFunction {
export interface Function<Obj extends MakerObject, Key extends keyof Obj> {
(): Obj["main"];
[key: Key]: Obj[Key];
}
export interface MainFunction {
(...args:any[]) : any;
}
export interface MakerObject {
[key: string]: any;
main?: MainFunction;
}
export type Maker = <Obj extends MakerObject, Key extends keyof Obj>(object:Obj) => ScopeFunction.Function<Obj, Key>;
}
// FUNC
var scopeFunction:ScopeFunction.Maker = (object) => {
// create main function if it doesn't exist
if (!object.main) object.main = function(){
alert("No main function for this scopeFunction");
};
// add all object keys to the main function that will be return
_.each(object, function(d,i){ object.main[i] = d; });
// return main function
return object.main;
};
// TEST
var test = scopeFunction({
a: 1,
b: "3",
main: () => { console.log("testLog"); return 0; }
})
var test1 = test(); // WORKS OK
var test2 = test.main(); // ALERT: Property 'main' doesn't exist on type 'Function<{ a: number; b: string; main: () => number }, "main" | "a" | "b">'
var test3 = test.a; // ALERT: Property 'a' doesn't exist on type 'Function<{ a: number; b: string; main: () => number }, "main" | "a" | "b">'
知道问题出在我的定义中吗?
答案 0 :(得分:1)
您的代码存在一些问题:
[key: Key]: Obj[Key]
无效,索引器参数必须是number
或string
(那些且只有那些类型有效)。您需要使用映射类型。(): Obj["main"]
不会是与Obj["main"]
相同类型的调用签名,它将是一个返回main
属性的函数。main
函数的类型过于通用,并且不会保留任何参数类型。 符合您期望的解决方案:
namespace ScopeFunction {
export type Function<Obj extends MakerObject<(...args: any[]) => any>> = Obj['main'] & {
[P in keyof Obj]: Obj[P];
}
export interface MakerObject<TMain extends (...args: any[]) => any> {
main?: TMain;
}
export type Maker = <TObj extends MakerObject<(...args: any[]) => any>>(object: TObj) => ScopeFunction.Function<TObj>;
}
// FUNC
var scopeFunction: ScopeFunction.Maker = (object) => {
// create main function if it doesn't exist
if (!object.main) object.main = function () {
alert("No main function for this scopeFunction");
};
// return main function
return Object.assign(object.main, object);
};
// TEST
var test = scopeFunction({
a: 1,
b: "3",
main: (param: number) => { console.log("testLog"); return param; }
})
var test1 = test(10);
var test2 = test.main(10);
var test3 = test.a;