TypeScript:正确处理递归类型

时间:2020-09-08 17:09:40

标签: typescript

编辑

我又走了一步。更复杂的示例如下所示(Playground):

type DeepFunctions = {
  [key: string]: ((...args: any[]) => any) | DeepFunctions
}

function changeDeepFunctions<T extends DeepFunctions>(deepFunctions: T): T {
  const copy = {...deepFunctions} as DeepFunctions;

  for(let key in copy) {
    const value = deepFunctions[key];
    if(value instanceof Function) {
      copy[key] = ((...args) => {
        console.log("hi");
        return value(...args);
      });
    } else {
      copy[key] = changeDeepFunctions(value);
    }
  }

  return copy as T;
}

一切都很好,输出与应有的样子完全一样。但是,我不明白为什么我需要这样做。也许还有人可以帮助我理解。

原始帖子

我是打字稿的新手,对于看似简单的问题,我找不到很好的解决方案。

您在此处看到的所有代码都记录在此PlayGround中。

由于我的实际示例过于繁琐,因此将其简化为以下这些示例(希望:)):

  1. 我想编写一个函数,该函数获取具有多个函数的对象并将其映射到具有映射函数的对象。有点难以描述,但是用代码易于理解:
type Functions = {
  [key: string]: (...args: any[]) => any;
};

export function changeFunctions<T extends Functions>(functions: T): T {
  const copy = { ...functions };

  for (let key in functions) {
    const func = functions[key];
    copy[key] = ((...args) => {
      console.log("hi");
      return func(...args);
    });
  }

  return copy;
}

如果您在操场上看了一下代码,便可以看到

copy[key] = ...

line产生类型错误:类型'(... args:any [])=> any'不能分配给类型'T [Extract ]'。(2322)< / em> 可以通过在作业末尾添加作为func类型来解决此问题,但这并不对。

有没有一种干净的方法可以写这个?

第二个示例扩展了第一个示例,因此解决方案可能类似:

  1. 作为1.的扩展,该函数现在应该能够正确转换包含函数的对象,而且还可以递归包含其他具有函数的对象。这是代码:
type DeepFunctions = {
  [key: string]: ((...args: any[]) => any) | DeepFunctions
}

function changeDeepFunctions<T extends DeepFunctions>(deepFunctions: T): T {
  const copy = {...deepFunctions};

  for(let key in deepFunctions) {
    const value = deepFunctions[key];
    if(value instanceof Function) {
      copy[key] = ((...args) => {
        console.log("hi");
        return value(...args);
      });
    } else {
      // it must be a DeepFunctions object
      copy[key] = changeDeepFunctions(value);
    }
  }

  return copy;
}

正如您在操场上看到的那样, copy [key] 分配失败的方式与上面的示例相同。另一个作业:

copy[key] = changeDeepFunctions(value);

不会引发错误。但是,类型仍然是错误的。将鼠标悬停在上可显示从不的类型。

您是否有任何提示如何正确地在Typescript中使用正确的类型编写此类方法?

0 个答案:

没有答案