Gql2ts - это инструмент, который используется для создания интерфейсов TypeScript из схемы GraphQL.

В прошлую пятницу в gql2ts был объединен массовый PR, что сделало его бесконечно более расширяемым и полезным.

Все пакеты, указанные ниже, были опубликованы npm с тегом next. Он будет опубликован как latest после еще нескольких тестов на этой неделе.

Вот краткий обзор изменений:

1. Использование запроса для создания интерфейсов

Первоначальной целью gql2ts было дать представление об ответах GraphQL API. Это было просто: взять схему, сгенерировать пространство имен, получить больше уверенности. Но он был слишком общим и включал слишком много информации. Например, если схема выглядела так:

type Query {
  customer: Customer;
}
type Customer {
  id: ID!;
  name: String!;
  occupation: String;
}

тогда интерфейсы будут выглядеть так:

namespace GraphQL {
  interface IQuery {
    __typename: string;
    customer: ICustomer;
  }
  interface ICustomer {
    __typename: string;
    id: string;
    name: string;
    occupation: string | null;
  }
}

Но если бы запрос выглядел так:

{
  customer {
    id 
  }
}

Тогда интерфейс будет иметь три посторонних поля (__typename, name, occupation), которых фактически не было в ответе.

Кроме того, если у запроса был псевдоним, интерфейсы были бы недействительными, например:

query CustomerWithJob {
  customer {
    id
    job: occupation
  }
}

И снова интерфейсы неверные. occupation по-прежнему будет в ICustomer интерфейсе, но на самом деле он должен быть job.

Этот вариант использования охватывает большую часть предполагаемой полезности библиотеки, и ее отсутствие было болезненным местом. В v1.0.0 это изменится. Теперь есть возможность включить файл с запросом и создать на его основе интерфейсы. (Старый вариант использования остался нетронутым, просто не задавайте запросы!)

Итак, для приведенного выше запроса сгенерированный интерфейс будет выглядеть примерно так:

interface CustomerWithJob {
  customer: SelectionOnCustomer;
}
interface SelectionOnCustomer {
  id: string;
  job: string;
}

Возможно, вы заметили SelectionOnCustomer интерфейс, я перейду к нему позже.

Подвыборки как отдельные интерфейсы

Проблема с другими инструментами, имеющими аналогичную функцию, заключается в том, что они генерируют код, который выглядит так:

interface Customer {
  employer: {
    name: string;
    employees: Array<{
      id: string;
      name: string;
    }>;
  }
}

В какой-то момент это становится довольно трудно читать. Кроме того, поскольку нет хорошего способа получить «подтип» из интерфейса TypeScript, это немного затрудняет написание реального кода. Рассмотрим следующий код:

const customer: Customer = getCustomer();
const formatEmployer = employer => { }
return formatEmployer(customer.employer)

Какой тип вы можете использовать для работодателя? Вам придется либо написать собственный интерфейс, который может стать несовместимым с вашим запросом, либо использовать тип any.

Вот почему gql2ts по умолчанию возвращает такой интерфейс, как:

interface Customer {
  employer: SelectionOnEmployer;
}
interface SelectionOnEmployer {
  name: string;
  employees: Array<SelectionOnEmployees>;
}
interface SelectionOnEmployees {
  id: string;
  name: string;
}

Теперь мы можем легко добавить проверку типов к предыдущему примеру кода:

const customer: Customer = getCustomer();
const formatEmployer = (employer: SelectionOnEmployer) => { }
return formatEmployer(customer.employer);

Он также имеет встроенный механизм кэширования, поэтому повторяющиеся имена не создаются (например, два интерфейса с именем SelectionOnCustomer). Если имя использовалось ранее и запрашиваются другие поля, «высокотехнологичный счетчик» добавит порядковый номер в конец имени. 😉

Если по какой-то причине функция подтипа нежелательна, ее можно отключить, предоставив альтернативную функцию generateSubTypeInterfaceName, которая возвращает null (или, если не проверка типов, любое ложное значение).

2. Программное использование

gql2ts был изначально разработан как простой интерфейс командной строки. Однако в v1.0.0 он обеспечивает первоклассную поддержку для программного использования. Установка пакетов @gql2ts/from-schema или @gqlts/from-query предоставит вам доступ к тем же функциям, которые использует интерфейс командной строки. Это чрезвычайно полезно, если вы генерируете определения типов как часть grunt / gulp / brunch / etc. задача или загрузчик веб-пакетов. Фактически, в Аванте мы используем пакет @gql2ts/from-query именно так. Наш скрипт читает query.graphql файлы и генерирует дополнительные query.graphql.d.ts файлы с определениями типов.

3. Возможность отмены форматирования по умолчанию.

Не у всех одинаковый стиль кода, поэтому программы форматирования по умолчанию с жестким кодированием могут быть вредны для других пользователей. gql2ts теперь позволяет передавать переопределения для значений по умолчанию. Вам просто нужно создать файл, который предоставляет эти переопределения, и выполнить экспорт по умолчанию (или module.exports = { default: { ...overrides } }). Кроме того, эти переопределения можно опубликовать npm и повторно использовать в других проектах.

4. Языковая поддержка

gql2ts был явно создан для поддержки TypeScript. Однако TypeScript - не единственный язык со строгой типизацией, который используют люди. Поскольку средства форматирования по умолчанию можно переопределить, это делает поддержку различных целей невероятно простой. Например, @gql2ts/language-flow - это пример таргетинга на поток вместо TypeScript. Документы по разработке новых языков скоро появятся, но до тех пор пакет @gql2ts/types будет иметь тип, который ожидается от языка.

5. Лерна

gql2ts перешла на использование lerna для управления своим репо. Это позволяет чрезвычайно легко разрабатывать новые модульные компоненты.

6. Переписано на TypeScript.

Забавно, что инструмент, разработанный для TypeScript, не был написан на нем, но все началось с быстрого (около 100 строк) взлома. Естественно, предпочтительным языком был Javascript.

7. Отказ от поддержки узла 4/5.

Чтобы использовать _33 _ / _ 34_ без дополнительных полифиллов, нужно было отбросить узел 4/5. Также были удалены предыдущие полифиллы. Выпуск Node 8 планируется в этом месяце, поэтому 6/7/8 должно быть разумным требованием.

Я очень рад этому выпуску и потенциальному будущему, которое есть у этой более расширяемой и функциональной версии gql2ts. В Аванте мы использовали альфа-версии, и это определенно улучшило качество набора текста.