Как использовать Facebook Relay в приложении React, написанном на TypeScript (TSX)?

Я хочу написать новое веб-приложение на React, которое использует Relay для связи с GraphQL сервер. Недавно была введена поддержка JSX для TypeScript. Но на DefinitelyTyped нет файла объявления типов (.d.ts) для Relay. Как я могу написать свое приложение на TypeScript без необходимости сначала писать файл типизации для Relay?


person Korneel    schedule 07.12.2015    source источник


Ответы (1)


Typescript не требует, чтобы у вас были типизации для всех используемых вами библиотек, это просто настоятельно рекомендуется. Чтобы использовать Relay без ввода:

import * as React from "react"
let Relay = require("react-relay")

interface HelloProps extends React.Props<HelloComponent> {
  viewer: {
    message: string
  }
}

class HelloComponent extends React.Component<HelloProps,void> {
  render() {
    return <div>Hello { this.props.viewer.message }</div>
  }
}

let Hello = Relay.createContainer(HelloComponent, {
  fragments: {
    viewer: () => Relay.QL`fragment on Viewer { message }`
  }
})

Затем используйте Hello как обычный компонент Relay. Идея состоит в том, что require — это функция, которая принимает строку и возвращает any, поэтому вы можете использовать переменную Relay, как в ванильном Javascript.

Если вы не используете типизацию Node.JS, вам может потребоваться добавить типизацию для require. Где-нибудь в ваших файлах d.ts добавьте:

interface NodeRequireFunction {
  (id: string): any;
}

declare var require: NodeRequireFunction;
person Gunchars    schedule 07.12.2015
comment
Спасибо, что указали, что мне нужно использовать типизацию Node.js. Но теперь я получаю следующую ошибку: ошибка TS2503: не удается найти пространство имен «Реле». - person Korneel; 08.12.2015
comment
interface HelloProps extends Relay.Props<HelloComponent> должно быть interface HelloProps extends React.Props<HelloComponent> - person Korneel; 08.12.2015
comment
Когда я пытаюсь определить маршрут с помощью class MyRoute extends Relay.Route {/* ... */}, TSC выводит error TS2507: Type 'any' is not a constructor function type.. Как бы вы решили эту ошибку? - person Korneel; 08.12.2015
comment
@Korneel, здесь вам нужно либо добавить некоторые типы, либо избегать использования классов ES6. Пользовательские маршруты не обязательно должны быть экземплярами класса, поэтому другой альтернативой является просто использование простых объектов, как показано в первом примере здесь: facebook.github.io/relay/docs/ - person Gunchars; 08.12.2015
comment
Спасибо. Это работает, когда маршрут определен как объект. И все же, как будет выглядеть файл .d.ts с типизациями для Relay.Route? Я пытался создать такой файл, но безуспешно. - person Korneel; 08.12.2015
comment
Вот типизация, которую я использую: gist.github.com/guncha/c5425166a18123995898. Они довольно специальные, так что ожидайте, что что-то сломается. Вы можете видеть, что Route — это просто класс, который принимает некоторые переменные. Relay меняется довольно быстро, поэтому может пройти некоторое время, прежде чем мы получим стабильные типизации. До тех пор лучше выяснить, как написать их самостоятельно. - person Gunchars; 08.12.2015
comment
Большое спасибо! Действительно :) Мне пришлось добавить var DefaultNetworkLayer; к предоставленным вами типам, чтобы иметь возможность установить сетевой уровень по умолчанию. Мне определенно придется провести некоторое исследование по написанию пользовательских файлов типизации. - person Korneel; 09.12.2015
comment
Как преобразовать Relay.QLfragment on Viewer { message } в ES5, чтобы браузер мог его понять? Подключаемый модуль Babel Relay делает это, но поскольку компилятор TypeScript уже транспилирует его во что-то другое, подключаемый модуль Babel Relay не преобразует запросы Relay, поэтому браузер выдает ошибку: Uncaught Invariant Violation: RelayQL: Неожиданный вызов во время выполнения. Либо преобразование Бабеля не было настроено, либо ему не удалось идентифицировать этот сайт вызова. Убедитесь, что он используется дословно как Relay.QL. - person Korneel; 15.01.2016
comment
stackoverflow.com/questions/34815578/ - person Korneel; 15.01.2016