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

Relaterte artikler