【问题标题】:Define a mapped Record type where every K in Record<T, K> depends on the value of T?定义一个映射记录类型,其中 Record<T, K> 中的每个 K 都依赖于 T 的值?
【发布时间】:2019-06-25 03:56:42
【问题描述】:

这是我大约三周前提出的这个问题的延伸:Set the keys of an interface to the possible values of a different interface?

简短的版本是我有以下类型定义

interface SuccessStatus {
  type: 'success';
  payload: string;
}

interface LoadingStatus {
  type: 'loading';
} 

interface ErrorStatus {
  type: 'error';
  error: string;
}

type RequestStatus = SuccessStatus | LoadingStatus | ErrorStatus;

以及以下映射的 Record 类型来定义一个对上述每个状态都有一个“处理程序”的对象:

type RequestHandlerVisitor = Record<
  RequestStatus["type"], 
  (status: RequestStatus) => void
>;

对于每个T,都有一个K 函数。

这将定义一个看起来像这样的对象:

const statusVisitor: RequestHandlerVisitor = {
  "success": (status: RequestStatus) => { ... },
  "loading": (status: RequestStatus) => { ... },
  "error": (status: RequestStatus) => { ... },
}

现在,我想定义一个类似的类型,其中K 的值根据T 的哪个键而变化,因此它看起来像这样:

const statusVisitor: NewRequestHandlerVisitor = {
  "success": (status: SuccessStatus) => { ... },
  "loading": (status: LoadingStatus) => { ... },
  "error": (status: ErrorStatus) => { ... },
}

在这种情况下,函数K 的第一个参数的值会根据T 的变化而变化。

一种选择是像这样对该类型进行硬编码:

interface NewRequestHandlerVisitor {
  "success": (status: SuccessStatus) => void;
  "loading": (status: LoadingStatus) => void;
  "error": (status: ErrorStatus) => void;
}

这将满足我在这种特定情况下的需求,但当我有更多“状态”类型时变得笨拙,每个类型都需要该类型的新条目。

有没有办法动态定义类似的东西?

谢谢!

【问题讨论】:

    标签: typescript


    【解决方案1】:

    您可以使用自定义映射类型和Extract 条件类型来做到这一点:

    interface SuccessStatus {
      type: 'success';
      payload: string;
    }
    
    interface LoadingStatus {
      type: 'loading';
    } 
    
    interface ErrorStatus {
      type: 'error';
      error: string;
    }
    
    type RequestStatus = SuccessStatus | LoadingStatus | ErrorStatus;
    
    type RequestHandlerVisitor = {
      [P in RequestStatus["type"]]: (s: Extract<RequestStatus, { type: P }>) => void
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-21
      • 2019-02-02
      • 1970-01-01
      • 1970-01-01
      • 2021-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多