我正在尝试为具有名为camelcaseKeys
的属性的类(最初为Javascript)编写类型。如果将其设置为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()
})()
我为每个响应定义了两个接口,所有属性都设置为camelCase或snake_case,但是我不知道如何使打字稿有条件地选择一个。
//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>
我不知道还能尝试什么。谢谢您的帮助!
答案 0 :(得分:2)
在没有您的APIClass
定义的情况下,我将不得不自行整理内容。这里的基本问题是,如果APIClass
需要保持跟踪是驼峰式还是蛇形,则这种区别将需要成为类类型本身的一部分。我可以通过将APIClass
generic设置为相关的布尔类型来做到这一点:
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 extends true ? camelType : snake_type
是什么时,易于使用诸如B
之类的条件类型的值,如果B
仍然是未解析的泛型类型参数,则更难使用。因此,getLoginInfo()
的实现可能要求您使用一些type assertions等来使编译器确信要返回的内容与该类型匹配。但是您并不是在问实现问题,所以我将其保留在那里。
好的,希望能有所帮助;祝你好运!