TypeScript 2.8:简化类型安全还原器?

TypeScript 2.8:简化类型安全还原器?,typescript,Typescript,我正在阅读这篇文章,我受到启发,通过基于myActionFunction的TypeofMyActionFunction使用ReturnType,简化了我的减速机 然而,在翻译过程中似乎丢失了一些东西,因为如果我用下面的东西显式地创建动作类型 export interface MyFirstAction extends Action<MyEnum.FirstAction> { someProperty: string; } export interface MySecondAc

我正在阅读这篇文章,我受到启发,通过基于myActionFunction的
TypeofMyActionFunction
使用
ReturnType
,简化了我的减速机

然而,在翻译过程中似乎丢失了一些东西,因为如果我用下面的东西显式地创建动作类型

export interface MyFirstAction extends Action<MyEnum.FirstAction> {
    someProperty: string;
}
export interface MySecondAction extends Action<MyEnum.SecondAction> {
    someOtherProperty: number;
}
这是所有类型安全的,并且是开箱即用的,不幸的是,如果我使用

type MyFirstAction = ReturnType<typeof firstAction>;
type MySecondAction = ReturnType<typeof secondAction>;
type MyFirstAction=ReturnType;
类型MySecondAction=ReturnType;
而不是显式声明我的操作接口

例如,在第二个案例块中,我会得到类似于
TS2339属性“someOtherProperty”在类型上不存在…
,因为如果使用
ReturnType
而不是显式接口推断类型,则类型系统似乎无法区分它们

为什么会这样,我能做些什么吗(这样我就可以简化代码,减少工作量,并且同样开心)


谢谢

问题是Typescript不会为对象文字属性推断文字类型,因此
{type:MyEnum.FirstAction,someProperty}
的类型将是
{type:MyEnum,someProperty:string}
而不是
{type:MyEnum.FirstAction,someProperty:string}
。最简单的解决方案是使用类型断言强制编译器推断文字类型而不是枚举类型:

type MyFirstAction = ReturnType<typeof firstAction>;
type MySecondAction = ReturnType<typeof secondAction>;

export const firstAction = (someProperty: string) => ({ type: MyEnum.FirstAction as MyEnum.FirstAction, someProperty });
export const secondAction = (someOtherProperty: number) => ({ type: MyEnum.SecondAction as MyEnum.SecondAction, someOtherProperty });

export const reducer: Reducer<MyModel, Action> = (state: MyModel = initialState, action: MyFirstAction | MySecondAction) => {
    switch (action.type) {
        case MyEnum.FirstAction: {
            const x = action.someProperty; // x is string
            return state;
        }
        case MyEnum.SecondAction: {
            const y = action.someOtherProperty; // y is number
            return state;
        }
    }
}
type MyFirstAction=ReturnType;
类型MySecondAction=ReturnType;
export const firstAction=(someProperty:string)=>({type:MyEnum.firstAction作为MyEnum.firstAction,someProperty});
export const secondAction=(someOtherProperty:number)=>({type:MyEnum.secondAction作为MyEnum.secondAction,someOtherProperty});
导出const reducer:reducer=(state:MyModel=initialState,action:MyFirstAction | MySecondAction)=>{
开关(动作类型){
案例MyEnum.FirstAction:{
const x=action.someProperty;//x是字符串
返回状态;
}
案例MyEnum.SecondAction:{
const y=action.someOtherProperty;//y是数字
返回状态;
}
}
}
type MyFirstAction = ReturnType<typeof firstAction>;
type MySecondAction = ReturnType<typeof secondAction>;
type MyFirstAction = ReturnType<typeof firstAction>;
type MySecondAction = ReturnType<typeof secondAction>;

export const firstAction = (someProperty: string) => ({ type: MyEnum.FirstAction as MyEnum.FirstAction, someProperty });
export const secondAction = (someOtherProperty: number) => ({ type: MyEnum.SecondAction as MyEnum.SecondAction, someOtherProperty });

export const reducer: Reducer<MyModel, Action> = (state: MyModel = initialState, action: MyFirstAction | MySecondAction) => {
    switch (action.type) {
        case MyEnum.FirstAction: {
            const x = action.someProperty; // x is string
            return state;
        }
        case MyEnum.SecondAction: {
            const y = action.someOtherProperty; // y is number
            return state;
        }
    }
}