[英]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.