TypeScript递归泛型参数类型

时间:2018-09-30 13:28:43

标签: typescript typescript-typings

我正在尝试创建转换器类,以将方法图转换为方法结果图。每个方法都有一个参数(方法结果图)。 但是我不能输入参数。有可能吗?

TypeScript游乐场:here

"use strict"
/**
 * Converter of object of methods into object of methods results.
 */
class GettersBuilder<M extends { [index: string]: (methods: any) => any }> {
  public results: { [P in keyof M]: ReturnType<M[P]> };
  constructor(methods: M) {
    this.results = Object.keys(methods).reduce((acc, key) => {
      const method = methods[key];
      return Object.defineProperty(acc, key, {
        get: () => {
          return method(this.results);
        }
      });
    }, {});
  }
}

const gb = new GettersBuilder({
  test1: () => 0,
  test2: () => null,
  test3: (results /* typed as any */) => results.test1
});

const res1: number = gb.results.test1 /*number*/; // typed correctly
const res2: null = gb.results.test2 /*null*/; // typed correctly
const res3A: number = gb.results.test3 /*number*/; // typed incorrectly as any instead of number
const res3B: string = gb.results.test3 /*number*/; // Error is not catched.

由于类型(methods: any) => any,现在无法进行键入。但是当我将类型更改为(methods: { [P in keyof M]: ReturnType<M[P]> }) => any时 然后将GettersBuilder.results的类型转换为任意值。

TypeScript游乐场here

"use strict"
/**
 * Converter of object of methods into object of methods results.
 */
class GettersBuilder<M extends { [index: string]: (methods: { [P in keyof M]: ReturnType<M[P]> }) => any }> {
  public results: { [P in keyof M]: ReturnType<M[P]> };
  constructor(methods: M) {
    this.results = Object.keys(methods).reduce((acc, key) => {
      const method = methods[key];
      return Object.defineProperty(acc, key, {
        get: () => {
          return method(this.results);
        }
      });
    }, {});
  }
}

const gb = new GettersBuilder({
  test1: () => 0,
  test2: () => null,
  test3: (results /* typed as any */) => results.test1
});

const res1: number = gb.results.test1 /*number*/; // typed incorrectly as any instead of number
const res2: null = gb.results.test2 /*null*/; // typed incorrectly as any instead of null
const res3A: number = gb.results.test3 /*number*/; // typed incorrectly as any instead of number
const res3B: string = gb.results.test3 /*number*/; // Error is not catched.

0 个答案:

没有答案