簡體   English   中英

復雜類型層次結構映射葉子到“未知”類型

[英]Complex type hierarchy mapping leafs to `unknown` type

我正在嘗試為 API 門面構建一個靈活的通用基礎 class。 這些外觀將定義一組返回特定類型的 HTTP 請求。 這些定義用於構建定制的請求注冊表,並在每個外觀的基礎上進行跟蹤。 我希望這些請求能夠提供所有類型信息,但是我認為我在映射類型方面存在問題,因為在其核心我使用的是`FacadeResultTypes = Record<string, unknown>;

這是一個 TS 游樂場,我在其中重新創建了類型生態系統。 上半部分是層次結構的設置,下半部分是重現我的問題的有限示例。

///////////////////
//  Types setup  //
///////////////////

// Convenience operator
type ValueOf<T> = T[keyof T];

// Describes an HTTP request's name and result type - implemented by an individual facade service.
// Note that the `unknown` type here is resulting in the issue.
type FacadeResultTypes = Record<string, unknown>;

// Defines a single type of request made by an API facade. Tracks number of inflight requests, errors, and latest value (value type is critical)
type FacadeRequest<T extends ValueOf<FacadeResultTypes>> = {
  inFlight: number;
  latest: T|undefined;
  error: string|undefined;
}

// A dictionary to look up FacadeRequests by name (name comes from the FacadeResultTypes keys, value is individual requests)
type FacadeRequestDictionary<ResultTypes extends FacadeResultTypes>
  = Record<keyof ResultTypes, FacadeRequest<ValueOf<ResultTypes>>>;

// Tracks the latest request to complete, as well as contains a FacadeRequestDictionary of all requests for the facade
type FacadeRequestRegistry<ResultTypes extends FacadeResultTypes> = {
  latest: FacadeRequest<ValueOf<ResultTypes>> | undefined;
  all: FacadeRequestDictionary<ResultTypes>;
}



/////////////////////
//  Example usage  //
/////////////////////

interface ExampleResponseType {
  test: string;
  test2: number;
}

interface ExampleFacadeResultTypes extends FacadeResultTypes {
  exampleRequest: ExampleResponseType;
  // other request name/response type pairs go in this list
}

const exampleRegistry: FacadeRequestRegistry<ExampleFacadeResultTypes> = {
  latest: undefined,
  all: {
    exampleRequest: {     // <-- Maps to facadeRequest<unknown>
      inFlight: 0,
      latest: undefined,  // <-- Maps to `unkonwn`
      error: undefined,
    }
    // Other request types defined in the ExampleFacadeResultTypes interface would show up here
  }
};

// PROBLEM:
// While exampleRegistry and exampleRegistry.all map to their correctly resolved types, exampleRegistry.all.exampleRequest maps to facadeRequest<unknown> and its child .latest also maps to unknown.
// I would like those `unknown` types to map to their corresponding FacadeResultTypes.

// Specifically, I want exampleRegistry.all.exampleRequest.latest to map to ExampleResponseType.
exampleRegistry.all.exampleRequest.latest;

如您所見,我不希望unknown (這需要實現者進行類型轉換)出現在對層次結構中最低級別元素的最終引用中。

有人看到我在這里做錯了嗎? 謝謝你的幫助。

// Convenience operator
type ValueOf<T> = T[keyof T];

我不確定你為什么有這種ValueOf類型。 那只會做:

Type A = { a: 1, b: 2 }
Type B = ValueOf<A> // 1 | 2

我看不出這對您的問題有何幫助。

如果你完全刪除它,我認為一切都會如你所願。

exampleRegistry.all.exampleRequest.latest; //  ExampleFacadeResultTypes | undefined

游樂場

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM