簡體   English   中英

打字稿映射類型組合

[英]Typescript mapped type composition

按照這個問題Typescript 自定義映射類型(感謝 Titian Cernicova-Dragomir!)
我有這個映射類型:

export type ToArray<T> = {
    [P in keyof T]: T[P] extends Vector<infer U> ? Array<U> : T[P]
}

現在,我想和 Pick 一起加入。

<Pick<ToArray<Tag>, 'id' | 'name' | 'children' | 'hierarchyName'>>{
    id: t.id,
    name: t.name,
    children: t.children.toArray()
}

但是,編譯器不會強迫我添加hierarchyName ,如果我使用,就會發生這種情況:

<Pick<Tag, 'id' | 'name' | 'children' | 'hierarchyName'>>

怎么樣?

我假設有一些定義與您的代碼中的定義相似(您的實際代碼可能不同,但此代碼足以說明問題):

interface Vector<E> {
    elements: E[];
    toArray(): E[];
}

interface Tag {
    id: string;
    name: string;
    children: Vector<Tag>;
    hierarchyName: string;
}

let t: Tag;

您是說當此初始化程序中缺少一個屬性時,您會收到預期錯誤:

const v1 = <Pick<Tag, 'id' | 'name' | 'children' | 'hierarchyName'>>{
    id: t.id,
    name: t.name,
    children: t.children.toArray()
};

讓我們嘗試將其簡化為一個最小的示例:刪除Pick ,並刪除所有屬性的初始化:

const v2 = <Tag>{
};

沒有錯誤。

為什么? 因為<Tag>{}類型斷言,所以它與{} as Tag相同,因為它{} as Tag - 您迫使編譯器相信該值實際上具有Tag類型。

編譯器很少會報告類型斷言的錯誤,畢竟類型斷言是告訴編譯器“我知道的更好”的一種方式。 在您的情況下,報告僅是因為Tag是遞歸類型,它具有類型為Tag[] children屬性,並且以某種方式使編譯器相信某個值永遠無法與該類型兼容:

// error
const v2 = <Tag>{       
    children: t.children.toArray()
};

與轉化ToArray制式非遞歸: children在轉化型保持與Tag類型,它是從封閉的類型,這使得錯誤走開不同。

捕獲這些錯誤的正確方法是對變量聲明使用類型注釋,而不是類型斷言:

const v3: Tag = {}; // error

暫無
暫無

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

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