Используя Unstated с TypeScript и React, как получить экземпляр типизированного контейнера внутри дочерних элементов <Subscribe>?
В моем приложении React я использую Unstated для управления общим состоянием, но я сталкиваюсь с проблемой использования этого с TypeScript: <Subscribe>
Компонент передает мне экземпляр моего состояния, который напечатан как Container<any>
, Это означает, что он должен быть приведен к моему типу, например Container<MyState>
прежде чем я смогу безопасно использовать его.
Если вместо этого я хотел, чтобы Unstated передал мне уже набранный экземпляр моего контейнера, как я должен обернуть и / или разветвить исходный код Unstated и / или его типизированный файл, чтобы при получении Container
Например, он напечатан как Container<MyState>
?
Кстати, особая причина, по которой я хочу получить переданный типизированный контейнер, заключается в том, что я могу использовать деструктурирование сложного состояния без необходимости переключаться на использование блочной функции жирных стрелок, которая является гораздо более многословной.
Вот упрощенный пример кода, который я хотел бы написать:
function Counter() {
return (
<Subscribe to={[CounterContainer]}>
{({increment, decrement, state}) => (
<div>
<button onClick={() => decrement()}>-</button>
<span>{state.count}</span>
<button onClick={() => increment()}>+</button>
</div>
)}
</Subscribe>
);
}
А вот текущий способ, которым я пишу это, в упрощенном неустановленном примере с использованием TypeScript:
import React from 'react';
import { render } from 'react-dom';
import { Provider, Subscribe, Container } from 'unstated';
interface CounterState {
count: number
};
class CounterContainer extends Container<CounterState> {
public state = {
count: 0
};
public increment() {
this.setState({ count: this.state.count + 1 });
}
public decrement() {
this.setState({ count: this.state.count - 1 });
}
}
function Counter() {
return (
<Subscribe to={[CounterContainer]}>
{(counter: CounterContainer) => {
const {increment, decrement, state} = counter;
return (
<div>
<button onClick={() => increment()}>-</button>
<span>{state.count}</span>
<button onClick={() => decrement()}>+</button>
</div>
)
}}
</Subscribe>
);
}
render(
<Provider>
<Counter />
</Provider>,
document.getElementById('root')
);
1 ответ
Итак, глядя на PR, который первоначально добавил определение машинописного текста, мы заметили, что они не смогли найти способ автоматически обеспечить типизацию, которую вы ищете, поскольку что-то вроде $TupleMap не существует в TS, как в Flow и вместо этого вы должны вручную ввести набор текста.
Если ваша основная мотивация заключается в том, чтобы избежать лишних {} с помощью функции стрелки, вы можете вручную ввести набор текста и при этом выполнить ту же деструктуризацию. Итак, из вашего примера:
function Counter() {
return (
<Subscribe to={[CounterContainer]}>
{({increment, decrement, state}: CounterContainer) => (
<div>
<button onClick={() => increment()}>-</button>
<span>{state.count}</span>
<button onClick={() => decrement()}>+</button>
</div>
)
}
</Subscribe>
);
}
работает так же. Может быть, есть способ напечатать это автоматически в Typescript, но это вне моего понимания.