【问题标题】:Typescript type declaration for a complex function that returns itself返回自身的复杂函数的打字稿类型声明
【发布时间】:2018-04-07 11:40:59
【问题描述】:

我有以下 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;

};

我想在打字稿中正确定义这段代码,这就是我所做的,但是当我尝试访问返回的函数对象的键时,原子打字稿(这是我测试过的地方)会引发错误。 这是我当前代码的样子:

// 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">'

知道我的定义中的问题出在哪里吗?

【问题讨论】:

    标签: javascript typescript types


    【解决方案1】:

    你的代码有几个问题:

    1. 定义不编译[key: Key]: Obj[Key] 无效,索引器参数必须是numberstring(只有那些类型才有效)。您需要改用映射类型。
    2. (): Obj["main"] 不会是与 Obj["main"] 相同类型的调用签名,而是会返回 main 的任何属性的函数。
    3. 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;
    

    【讨论】:

      猜你喜欢
      • 2017-08-12
      • 2015-08-10
      • 2020-05-02
      • 1970-01-01
      • 1970-01-01
      • 2022-01-12
      相关资源
      最近更新 更多