簡體   English   中英

復雜的泛型類型約束和類型推斷

[英]complex generic type constraint and type inferrance

我正在嘗試在 TypeScript 中構建一個微型 ORM,但我面臨這個編譯問題:

Type 'TObject' does not satisfy the constraint '{ [k in k]: object; }'.
  Type 'object' is not assignable to type '{ [k in k]: object; }'.

有誰知道為什么這個代碼示例會引發編譯錯誤? 以及如何解決?

type NavigationProperties<T, TKey extends keyof T> = T[TKey] extends object ? TKey : never;
 type Relationship<T extends { [k in TMember]: TTarget }, TMember extends keyof T, TTarget extends object = object> = {
    name: TMember,
    isComposite?: boolean,
};
class A<TObject extends object>
{
    public readonly relationships: Partial<{ [k in NavigationProperties<TObject, keyof TObject>]: Relationship<TObject, k> }> = { }
}

操場

編輯

根據 Shivam 的要求,我正在為其添加更多上下文:當我有混合類型或不匹配類型時,我也想讓它工作: 操場

問題

在類型Relationship中, T被約束為{ [k in TMember]: TTarget } ,在聲明屬性relationships時,傳遞了TObject ,其類型為object ,它是{ [k in TMember]: TTarget }的超類型。 因此不兼容。

解決方案

type NavigationProperties<T, TKey extends keyof T> = T[TKey] extends object ? TKey : never;

type TObject<T extends object, TType extends object> = { [K in keyof T]: TType }

type Relationship<T extends TObject<T, TType>, TKeys extends keyof T, TType extends object> = {
    name: TKeys,
    isComposite?: boolean,
};

type Relationships<T extends TObject<T, TType>, TType extends object> = {
    [K in NavigationProperties<T, keyof T>]?: Relationship<T, K, TType>
}

class A<T extends TObject<T, TType>, TType extends object = object> {
    public readonly relationships: Relationships<T, TType> = { }
}

// example usage
type MyType = {
    prop1: number
    porp2: string
}

type X = {
    a: MyType
    b: MyType
}

declare const obj: A<X>

obj.relationships // type is Relationships<X, object>

// type of obj1.relationships.a is Relationship<X, "a", object>
obj.relationships.a?.name // "a"
obj.relationships.b?.name // "b"

declare const obj1: A<X, MyType>

obj1.relationships // type is Relationships<X, MyType>

// type of obj1.relationships.a is Relationship<X, "a", MyType>
obj1.relationships.a?.name // "a"
obj1.relationships.b?.name // "b"

操場

暫無
暫無

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

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