Typescript - Betinget returtype basert på klasseegenskap
Jeg prøver å skrive typings for en klasse (opprinnelig Javascript) som har en egenskap kalt camelcaseKeys. Hvis den er satt til true, vil alle metodene som gjør et API-kall returnere et objekt med egenskapene konvertert til camelCase, og hvis den er satt til false returneres de i 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()
})()
Jeg definerte to grensesnitt for hvert svar med alle egenskapene satt til enten camelCase eller snake_case, men jeg vet ikke hvordan jeg får TypeScript til å velge én betinget.
//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>
Jeg vet ikke hva mer jeg kan prøve. Takk for all hjelp!
Svar #1
Uten din APIClass-definisjon må jeg finne på ting underveis. Det grunnleggende problemet her er at hvis APIClass trenger å holde oversikt over om det er en camelCase-type eller en snake_case-type, må denne distinksjonen være en del av klassetypen selv. Jeg ville gjort det ved å gjøre APIClass generisk i den relevante boolske typen:
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
}
}
Så nå vil returtypen til getLoginInfo() avhenge av B på den måten du ønsker:
const api = new APIClass("username", "password", { camelcaseKeys: true });
(async () => {
await api.login();
let result = api.getLoginInfo(); // cameltype
})();
Vennligst merk at verdier av betingede typer som B extends true ? camelType : snake_type er lett å bruke når du vet hva B er, og vanskeligere å bruke hvis B fortsatt er en uavklart generisk typeparameter. Så implementeringen av getLoginInfo() kan kreve at du bruker noen typepåstander eller lignende for å overbevise kompilatoren om at det du returnerer samsvarer med typen. Men du spør ikke om implementering, så jeg lar det være der.
Ok, håper det hjelper; lykke til!
Lenke til kode
