基于第一个函数的参数有条件返回函数的 typescript 自动完成

标签 typescript typescript-generics

我已经为此绞尽脑汁有一段时间了,所以我决定在 Stackoverflow 上提出这个问题,希望有人能够帮助我。这是我的问题的简化代码片段版本:TypeScript Playground

type options = "bar" | "foo";

interface barFunctions {
  barFunction: () => void;
}

interface fooFunctions {
  fooFunction: () => void;
}

interface returnFunctions {
  bar: barFunctions,
  foo: fooFunctions
}

const example = <T extends options>(options: options): returnFunctions[T] => {
  if (options === "bar") {
    return {
      barFunction() {
        console.log("It's the bar function");
      }
      // I don't expect an error here, the options parameter is set to "bar", so there is no need for a "fooFunction..."
    }
  }

  if (options === "foo") {
    return {
      fooFunction() {
        console.log("It's the foo function");
      }
      // I don't expect an error here, the options parameter is set to "foo", so there is no need for a "barFunction..."
    }
  }

  throw new Error(`Expected either foo or bar but got ${options}`)
}

解释一下:

我想在 example 上自动完成函数一旦以某个 option 执行参数。

所以如果我输入 example("foo").<autocompletion expects fooFunctions interface> 。所以它会告诉我example("foo").fooFunction()是唯一的选项,因为第一个函数的参数是“foo”。

如果我输入 example("bar").<autocompletion expects barFunctions interface> 。所以它会告诉我example("bar").barFunction()是唯一的选项,因为第一个函数的参数是“bar”。

但是现在的问题是,两个返回对象都期望另一个函数在那里,即使我不希望这样......

有 Typescript 专家可以帮助我吗?

最佳答案

有多种方法可以解决这个问题。大多数都不是类型安全的(例如重载或使用类型断言),因为它们无法为编译器提供验证函数实现中的逻辑的方法。

您的通用方法并不遥远。首先要修复的是泛型类型 T 不用于输入参数。让我们为参数 option 指定类型 T

const example = <T extends options>(option: T): returnFunctions[T] => {
  return {
    get bar() {
      return {
        barFunction() {
          console.log("It's the bar function");
        },
      };
    },
    get foo() {
      return {
        fooFunction() {
          console.log("It's the foo function");
        }
      }
    }
  }[option]
};

现在为了获得我们想要的类型安全,我们必须将函数实现转换为这种映射形状的结构。每个键都是一个getter,用于推迟每条路径的评估。我们这样做是为了避免每次调用函数时都必须计算所有路径。如果计算这些并不昂贵,这对您来说可能并不重要。

TypeScript 可以验证这个 map 形状的结构是否符合 returnFunctions[T] 类型。


Playground

关于基于第一个函数的参数有条件返回函数的 typescript 自动完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75220340/

相关文章:

function - 展开对象以作为函数参数传递

typescript - Lodash - '_' 指的是 UMD 全局和 lodash.js 不是模块错误

node.js - 您应该如何在 TypeScript 中为 Morgan 创建 Winston 记录器流

reactjs - React Typescript 功能组件语法错误

typescript - 使用泛型获取我的小 compose 函数的类型化结果

typescript - 更干净的功能重载,无需复制不改变的部分

具有枚举泛型类型的 Typescript 对象数组

javascript - JS/TS判断一个JSON对象是否实现类或接口(interface)

reactjs - 我的自定义身份验证 react-router 路由有什么问题?

typescript - 如何使用对枚举通用的类扩展通用接口(interface)?