使用redux,我最终在商店代码中编写了以下代码段:
type CombinedParamTypes<T extends {
[key: string]: (state: any, action: any) => any;
}> = T extends {
[key: string]: (state: infer R, action: any) => any;
} ? R : never;
type CombinedReturnTypes<T extends {
[key: string]: (...args: any) => any;
}> = T extends {
[key: string]: (...args) => infer R;
} ? R : never;
示例:
import camera from "./camera/reducer";
import settings from "./settings/reducer";
export const ALL_REDUCERS = {
camera,
settings,
};
const COMBINED_REDUCERS = combineReducers(ALL_REDUCERS);
export type FlatReduxState = CombinedParamTypes<typeof ALL_REDUCERS>;
// returns intersection type: ICameraState & ISettingsState
export type WhyDifferent = CombinedReturnTypes<typeof ALL_REDUCERS>;
// returns union type: ICameraState | ISettingsState
谁能解释为什么他们返回的方式不同?我意识到一个人在看一个参数,另一个人在看返回类型,但是这如何转换成决定交集与并集呢?
答案 0 :(得分:1)
函数类型为covariant in their return type and contravariant in the argument types。关于type inference in conditional types,在文档中也有说明:
[...]协变量位置中相同类型变量的多个候选导致推断联合类型[...]同样,反变量位置中相同类型变量的多个候选导致交集类型被推断[。]
对于您的reducer返回类型,TypeScript推断R
的所有实例化的通用 supertype ,这将导致返回类型的并集类型-ICameraState | ISettingsState
。反过来说,R
的函数参数中所有CombinedParamTypes
的实例化都将作为交集类型组合起来,以获得R
-{{1 }}。
当您第一次(和第二次-对我来说...)听到它时,协方差和反方差的基本概念有时会很难理解。某种意义上,协方差意味着当基本组件类型以函数,列表或其他更复杂的类型(高阶类型/ HOT)打包时,基本类型的子类型关系得以保留。逆变性是相反的-在函数中,子类型成为超类型,因为函数的参数类型是逆变量。
以this recommended article的狗和动物为类比的简单示例:
ICameraState & ISettingsState
希望,我可以解决一些问题。