I have a redux state like this
interface DataState {
dashboard: {
data: DashboardData | null
isLoading: boolean
error: string | null
}
policySearch: {
data: PolicySearchData | null
isLoading: boolean
error: string | null
}
other: {
someKey: someValue
}
}
and I have an action creator that toggles the isLoading
state in given field in the data state
toggleDataLoading('policySearch', true)
I don't want to send a wrong first parameter to toggleDataLoading
function so I have this:
type FieldsThatHaveLoadingState = 'dashboard' | 'policySearch
because some fields won't have isLoading
state
I tried to think of a way to programmatically collect the keys from the DataState
with Typescript. Something looks like this in javascript:
const keysIWant = {}
Object.keys(dataState).forEach(key => {
if(dataState[key].isLoading) keysIWant[key] = true
})
type FieldsThatHaveLoadingState = keyof typeof keysIWant
Is it possible to do this kind of a collection only using Typescript types and checks?
The approach shown below correctly limits valid keys to the function call.
The complexity of having to have nested distributive conditionals to express this will hopefully go away with the work on https://github.com/microsoft/TypeScript/issues/23188
interface DataState {
dashboard: {
isLoading: boolean
}
policySearch: {
isLoading: boolean
}
other: {
someKey: 'someValue'
}
}
type LoadableKey<T = keyof DataState> = T extends keyof DataState ? DataState[T] extends { isLoading: boolean } ? T : never : never
const toggleDataLoading = (stateKey: LoadableKey) => {
console.log(`Loading ${stateKey}`)
}
toggleDataLoading('dashboard');
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.