Typescript - 基于类属性的条件返回类型

标签 typescript conditional-types

我正在尝试为一个类(最初是 Javascript)编写类型,该类具有名为 camelcaseKeys 的属性。如果它设置为 true,那么进行 API 调用的所有方法都会返回一个对象,该对象的属性已转换为 camelCase,如果它设置为 false,则它们将以 snake_case 形式返回。

const api = new APIClass("username", "password", {camelcaseKeys: true});
(async () => {
    await api.login()
    /*Returns an object with camelCase or snake_case keys,
    depending on the value of camelcaseKeys.*/
    let result = api.getLoginInfo()
})()

我为每个响应定义了两个接口(interface),所有属性都设置为 camelCase 或 snake_case,但是我不知道如何让 typescript 有条件地选择一个。

//Doesn't work, type is camelType | snake_type
public getLoginInfo<T extends this>(): T["camelcaseKeys"] extends true 
? camelType : snake_type

//Doesn't work, type is camelType | snake_type
type GetCase<T extends APIClass, C, S> = T["camelcaseKeys"] extends true ? C : S
public getLoginInfo(): GetCase<this, camelType, snake_type>

我不知道还能尝试什么。感谢您的帮助!

最佳答案

如果没有您的 APIClass 定义,我将不得不边做边补。这里的基本问题是,如果 APIClass 需要跟踪它是驼峰式还是蛇式,则这种区分需要成为类类型本身的一部分。我会通过制作 APIClass generic 来做到这一点在相关的 bool 类型中:

class APIClass<B extends boolean> {
  constructor(
    public username: string,
    public password: string,
    public options: { camelcaseKeys: B }
  ) {}

  public async login() {}

  public getLoginInfo(): B extends true
    ? camelType
    : snake_type {
    return null!; // implement me later
  }
}

所以现在 getLoginInfo() 的返回类型将以您想要的方式取决于 B:

const api = new APIClass("username", "password", { camelcaseKeys: true });
(async () => {
  await api.login();
  let result = api.getLoginInfo(); // cameltype
})();

请注意像 B 这样的条件类型的值扩展为 true ?当您知道 B 是什么时,camelType : snake_type 很容易使用,如果 B 仍然是未解析的泛型类型参数,则更难使用。因此 getLoginInfo()实现可能需要您使用一些 type assertions或类似的东西让编译器相信你返回的东西与类型相匹配。但您没有询问实现情况,所以我会把它留在那里。

好的,希望对你有帮助;祝你好运!

Link to code

关于Typescript - 基于类属性的条件返回类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58188167/

相关文章:

javascript - !args.value || 的正确性args.value.length?

javascript - typescript 中服务的动态函数调用

javascript - 如果文本比容器长,如何使文本换行

javascript - 当我尝试在 javascript 中将日期转换为 toisostring 时,为什么要休息 1 天?

typescript :基于输入值(枚举)的函数返回类型

typescript - 从类的属性和方法中提取特定类型并将其添加到接口(interface)

typescript - 如何从泛型函数中的参数类型推断返回类型?

javascript - 无法使用 Angular 显示实时摄像机 RTSP 流

使用元组/联合支持进行深度转换的 TypeScript 映射类型

typescript - 将 TypeScript 接口(interface)的可选属性转换为可为 null 的属性