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