簡體   English   中英

遞歸部分<T>在打字稿中

[英]Recursive Partial<T> in TypeScript

我有這個界面:

export interface UserSettings
{
    one: {
        three: number;
        four: number;
    };
    two: {
        five: number;
        six: number;
    };
}

...並想把它變成這個:

export interface UserSettingsForUpdate
{
    one?: {
        three?: number;
        four?: number;
    };
    two?: {
        five?: number;
        six?: number;
    };
}

...但Partial<UserSettings>產生這個:

{
    one?: {
        three: number;
        four: number;
    };
    two?: {
        five: number;
        six: number;
    };
}

是否可以使用映射類型使所有深度的所有屬性都可選,還是必須為此手動創建接口?

隨着 2.8 中條件類型的落地,我們現在可以如下聲明遞歸部分類型。

type RecursivePartial<T> = {
  [P in keyof T]?:
    T[P] extends (infer U)[] ? RecursivePartial<U>[] :
    T[P] extends object ? RecursivePartial<T[P]> :
    T[P];
};

參考:

http://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html

您可以制作自己的映射類型,如下所示:

type RecursivePartial<T> = {
    [P in keyof T]?: RecursivePartial<T[P]>;
};

在此處輸入圖片說明

不幸的是,這不適用於數組類型的字段。 似乎也沒有一種方法可以進行條件類型映射; 即限制為原語。 請參閱https://github.com/Microsoft/TypeScript/pull/12114#issuecomment-259776847現在可能,請參閱其他答案。

我制作了一個庫tsdef ,它有許多這樣的常見模式/片段。

對於這種情況,您可以像下面這樣使用它:

import { DeepPartial } from 'tsdef';

let o: DeepPartial<{a: number}> = {};

提供的解決方案都不夠好。 這是一個解釋:

const x: RecursivePartial<{dateValue: Date}> = {dateValue: 0}; // ja-ja-ja

在上面的代碼中, dateValue的實際類型是RecursivePartial<Date> | undefined RecursivePartial<Date> | undefined允許分配任何值!!! dateValue預期類型只是Date ,但是規則T[P] extends object ? RecursivePartial<T[P]> T[P] extends object ? RecursivePartial<T[P]>太寬泛了。

解決方案是分離原語並消除extends object

export type RecursivePartial<T> = {
    [P in keyof T]?:
    T[P] extends Array<infer U> ? Array<Value<U>> : Value<T[P]>;
};
type AllowedPrimitives = boolean | string | number | Date /* add any types than should be considered as a value, say, DateTimeOffset */;
type Value<T> = T extends AllowedPrimitives ? T : RecursivePartial<T>;

暫無
暫無

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

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