我想避免这个“问题”,即在我的应用程序组件周围嵌套数十个提供程序,从而导致提供程序组件出现侧山般的层次结构。我想使用组合来组合这些提供程序。我的提供者通常都有价值观。我找到了一种使用 javascript (没有 typescript)来组合它们的方法 - 或者通过使用 Typescript 和
any
类型来组合它们 - 但我真的很想找到一种方法来组合可能有值或没有值的 Provider在 Typescript 中,不使用 any
类型。我认为阻碍我前进的只是我对 Typescript 的理解深度。这是最简单的示例,我可以轻松设计一个用 Typescript 编写的提供程序组合组件,该组件试图组合两个都有值的提供程序(我也想以类型安全的方式组合没有值的提供程序,但是我认为我在这里得到的 TS 错误说明了我一直在努力解决的问题的根源):
import React from "react"
import RefreshablePlayersContext from "contexts/RefreshablePlayersContext"
import RefreshableGamesContext from "contexts/RefreshableGamesContext"
import type { RefreshablePlayersContext as RefreshablePlayersContextType } from "types/RefreshablePlayersContext"
import type { RefreshableGamesContext as RefreshableGamesContextType } from "types/RefreshableGamesContext"
import type { Player } from "types/Player"
import type { Game } from "types/Game"
import type { RefreshableRequest } from "types/RefreshableRequest"
interface ProviderWithValue<ContextType> {
provider: React.Provider<ContextType>
value: ContextType
}
interface ProvidersProps {
children: React.ReactElement
}
const Providers = ({ children }: ProvidersProps): React.ReactElement => {
const [refreshableGames, setRefreshableGames] = React.useState<
RefreshableRequest<Game[]>
>({
status: "Not Started",
})
const [refreshablePlayers, setRefreshablePlayers] = React.useState<
RefreshableRequest<Player[]>
>({
status: "Not Started",
})
const providersWithValues: [
ProviderWithValue<RefreshableGamesContextType>,
ProviderWithValue<RefreshablePlayersContextType>,
] = [
{
provider: RefreshableGamesContext.Provider,
value: { refreshableGames, setRefreshableGames },
},
{
provider: RefreshablePlayersContext.Provider,
value: { refreshablePlayers, setRefreshablePlayers },
},
]
return providersWithValues.reduceRight((acc, CurrentProviderWithValue) => {
return (
// the Typescript error is on the following line; complaining about the
// value which is passed to the `value` prop below:
<CurrentProviderWithValue.provider value={CurrentProviderWithValue.value}>
{acc}
</CurrentProviderWithValue.provider>
)
}, children)
}
export default Providers
对于上面注释中提到的行,打字稿错误如下:
输入“RefreshableGamesContext | RefreshablePlayersContext' 不可分配给类型“RefreshableGamesContext & RefreshablePlayersContext”。 类型“RefreshableGamesContext”不可分配给类型“RefreshableGamesContext & RefreshablePlayersContext”。 类型“RefreshableGamesContext”缺少类型“RefreshablePlayersContext”中的以下属性:refreshablePlayers、setRefreshablePlayers
我之前没有见过 Typescript 的
&
运算符,但是查了一下之后,看起来它期望两个
value
值的 ProviderAndValue<T>
都具有它们各自拥有的属性;例如两个可能值的交集。 我不明白为什么会这样,因为我在输入时显式地输入了
ProviderWithValues
数组的每个索引:
const providersWithValues: [
ProviderWithValue<RefreshableGamesContextType>,
ProviderWithValue<RefreshablePlayersContextType>,
] = [
{
provider: RefreshableGamesContext.Provider,
value: { refreshableGames, setRefreshableGames },
},
{
provider: RefreshablePlayersContext.Provider,
value: { refreshablePlayers, setRefreshablePlayers },
},
]
有没有办法保持 Typescript 的类型安全(不使用
any
类型)来组合这两个接受不同类型值的提供程序?
(如果您的解决方案还规定以类型安全的方式编写没有 value prop 的 Provider,那就加分了!)