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

键入一个方法,该方法返回一个具有此属性的对象?

  •  -1
  • ThomasReggi  · 技术社区  · 6 年前

    我将如何键入此方法。make是一个函数

    abstract class Example{
      abstract from: string;
      abstract to: string;
      make (): string {
        return 'hi';
      }
      methods () {
        return ({
          from: {
            [this.from]: {
              to: {
                [this.to]: this.make,
              },
            },
          },
        });
      }
    }
    
    class Move extends Example {
      from = 'alpha';
      to = 'beta';
    }
    
    const x = (new Move()).methods().from;
    

    enter image description here

    0 回复  |  直到 6 年前
        1
  •  1
  •   ThomasReggi    6 年前

    您可以使用多态 this 在函数的返回类型注释中。您需要使用类型断言才能使实现工作,但派生类的类型将按预期进行。

    此外,派生类中的字段要么需要显式地类型化为字符串文本类型,要么声明为只读,以使编译器不会将类型扩展为 string :

    type MethodResult<TFrom extends string, TTo extends string> = {
        from: Record<TFrom, {
            to: Record<TTo, string>
        }>
    }
    abstract class Example{
      abstract from: string;
      abstract to: string;
      make (): string {
        return 'hi';
      }
      methods () : MethodResult<this['from'],this['to']> {
        return ({
          from: {
            [this.from]: {
              to: {
                [this.to]: this.make,
              },
            },
          },
        }) as any;
      }
    }
    class Move extends Example {
      readonly from = 'alpha';
      readonly to = 'beta';
    }
    
    const x = (new Move()).methods().from.alpha.to.beta;
    
        2
  •  0
  •   Evert    6 年前

    Typescript是一种编译时语言。因此,通常不可能执行运行时键入,并且 this 基本上是一种运行时状态。

    当然,单个抽象类型有可能根据实现返回不同的内容,但这必须在编译时完成。

    因此,如果您不熟悉这一点,一般的工具是泛型。

    这里有一个这样的例子 确切地 做你想做的,但给你一些接近这个的东西。

    type MoveAbstract = {
      from: {
         [s:string]: {
           to: {
             [s: string]: () => string
           }
         }
      }
    }
    
    abstract class Example<T extends MoveAbstract> {
      abstract from: string;
      abstract to: string;
      make (): string {
        return 'hi';
      }
    }
    
    type MakeMove = {
      from: {
         alpha: {
           to: {
             beta: () => string
           }
         }
      }
    }
    
    class Move extends Example<MakeMove> {
      from = 'alpha';
      to = 'beta';
      methods (): MakeMove {
        return ({
          from: {
            alpha: {
              to: {
                beta: this.make,
              },
            },
          },
        });
      }
    
    }
    
    const x = (new Move()).methods().from;
    

    我知道这不是 确切地 你正在寻找的,可能比你想要的重复更多,但从消费者的角度来看 Example 抽象类,您基本上可以实现这一点。

    也许可以进一步优化,但我不确定!