Typescript - условный тип возвращаемого значения, основанный на свойстве класса - PullRequest
2 голосов
/ 01 октября 2019

Я пытаюсь написать тип для класса (изначально 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()
})()

Я определил два интерфейса для каждого ответа со всеми свойствами, установленными в 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>

Я не знаю, что еще попробовать. Спасибо за любую помощь!

1 Ответ

2 голосов
/ 01 октября 2019

Без твоего 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() может потребовать от вас использования некоторых утверждений типа или чего-то подобного, чтобы убедить компилятор, что возвращаемая вещь соответствует типу. Но вы не спрашиваете о реализации, поэтому я оставлю это там.

Хорошо, надеюсь, это поможет;удачи!

Ссылка на код

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...