代码之家  ›  专栏  ›  技术社区  ›  olivierr91

从typescript中的lambda表达式检索属性名

  •  3
  • olivierr91  · 技术社区  · 6 年前

    我想强输入属性名

    myMethod(model => model.userId);
    
    public myMethod(model: () => any) {
        //Must print "userId"
    }
    

    我已经知道这不起作用,因为javascript将评估userid。

    在C中很容易做到:

    Get string property name from expression

    Retrieving Property name from lambda expression

    是否可以在typescript/javascript中执行此操作?

    2 回复  |  直到 6 年前
        1
  •  3
  •   Jonas Wilms    6 年前

    myMethod(model, "userId")
    

    function myMethod<T, K extends keyof T>(model: T, key: K) {
      const value = model[key];
      //...
     }
    

    Read on


    function myMethod(model: () => any) {
       const key = model.toString().split(".")[1];
       //...
    }
    
        2
  •  3
  •   jcalz    6 年前

    如果我理解您的要求,您将检查属性检索箭头函数,并返回

    type ValueOf<T> = T[keyof T];
    function evilMagic<T, V extends T[keyof T]>(
      f: (x: T)=>V
    ): ValueOf<{[K in keyof T]: T[K] extends V ? K : never}>;
    function evilMagic(f:(x: any)=>any): keyof any {
      var p = new Proxy({}, {
        get(target, prop) { return prop }
      })
      return f(p);
    }
    

    evilMagic 获取属性获取函数并尝试返回其返回的属性的名称。这个 keyof T T 是属性获取函数期望的参数。这个 的函数使用 Proxy p 它就像一个对象,其值总是与其键相同。也就是说, p.foo "foo" ,和 p.bar "bar" p[10] "10" .调用属性getter 还有,阿布拉卡达布拉,你有房产的名字。

    interface Person {
      name: string;
      age: number;
      numberOfLimbs: number;      
    }
    const m = evilMagic((x: Person) => x.age); // typed as "age"|"numberOfLimbs";
    console.log(m); // "age"
    

    在编译时,typescript只能告诉 m "age" "numberOfLimbs" number 如你所料。

    无论如何,希望能有所帮助。祝你好运!