【问题标题】:Typescript decorator type inferring issue打字稿装饰器类型推断问题
【发布时间】:2020-01-17 12:45:30
【问题描述】:

当我想键入 TS 装饰器的函数参数时,我遇到了问题。 考虑它在 redux 上下文中。这个装饰器 @OnAction 用它的 type 拦截动作。

我想要从我给装饰器的类型中,这个请求一个具有相应动作类型的函数。 基本上,使用@OnAction('history/modal/toggle'),我希望装饰器询问带有参数action: HistoryModalToggleAction 的函数。

但是使用以下代码,我的装饰器出现编译错误。

Playground

// Sample.ts

export interface HistoryModalReducerProps {
  visible: boolean;
  otherStuff: string;
}

export interface HistoryModalToggleAction extends Action<'history/modal/toggle'> {
  visible: boolean;
}

export type StoreAction = HistoryModalToggleAction | Action<'otherAction1'> | Action<'otherAction2'>;

export class Sample {

  @OnAction('history/modal/toggle')
  onToggle(state: Readonly<HistoryModalReducerProps>, action: HistoryModalToggleAction): Readonly<HistoryModalReducerProps> {

    if (!action.visible)
      return state;
    else
      return {
        ...state,
        visible: true
      };
  }

}
// OnAction.ts

type RestrictedMethod<A extends StoreAction> = (
  prototype: any,
  key: string,
  descriptor: TypedPropertyDescriptor<(
    state: any,
    action: A
  ) => any>
) => void;

export function OnAction<A extends StoreAction>(type: A['type']): RestrictedMethod<A> {

  const restrictedMethod: RestrictedMethod<A> = (prototype, key, descriptor) => {

    // ...

  };

  return restrictedMethod;
}

编译错误,简化,表示在我的函数中,HistoryModalToggleAction 不能分配给StoreAction。所以我的装饰器用action: StoreAction而不是action: HistoryModalToggleAction等待一个函数。即使我对这种缺乏推理视而不见,这似乎是错误的,这些类型是兼容的。

我的打字稿版本是3.5.3

感谢您的帮助。

【问题讨论】:

    标签: typescript redux decorator typescript-typings


    【解决方案1】:

    找到解决方案!

    我必须更改 OnAction 签名的类型以缩小我的操作类型:

    type NarrowAction<T, N> = T extends Action<N> ? T : never;
    
    export function OnAction<T extends StoreAction['type']>(type: T): RestrictedMethod<NarrowAction<StoreAction, T>> {
    
      return (prototype, key, descriptor) => {
    
        // ...
    
      };
    }
    

    现在可以了! Playground

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-02-15
      • 1970-01-01
      • 2018-06-09
      • 2020-04-02
      • 2020-12-20
      • 2016-08-03
      • 2019-04-10
      相关资源
      最近更新 更多