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