[英]Apply a complex generic type recursively
感謝 Nit 的回答,我有一個泛型類型NullValuesToOptional
,它生成每個可空值都變為可選的類型:
type NullValuesToOptional<T> = Omit<T, NullableKeys<T>> & Partial<Pick<T, NullableKeys<T>>>;
type NullableKeys<T> = NonNullable<({
[K in keyof T]: T[K] extends NonNull<T[K]> ? never : K
})[keyof T]>;
type NonNull<T> = T extends null ? never : T;
有用:
interface A {
a: string
b: string | null
}
type B = NullValuesToOptional<A>; // { a: string, b?: string | null }
現在我想讓NullValuesToOptional
遞歸:
interface C {
c: string
d: A | null
e: A[]
}
type D = NullValuesToOptional<C>;
// { c: string, d?: NullValuesToOptional<A> | null, e: NullValuesToOptional<A>[] }
可能嗎?
更新:包括 TS 3.7 版本 + 數組類型
你的意思是這樣的嗎?
TS 3.7+(arrays 中的通用類型 arguments 現在可以是圓形的):
type RecNullValuesToOptional<T> = T extends Array<any>
? Array<RecNullValuesToOptional<T[number]>>
: T extends object
? NullValuesToOptional<{ [K in keyof T]: RecNullValuesToOptional<T[K]> }>
: T;
< TS 3.7(需要類型解析延遲接口):
type RecNullValuesToOptional<T> = T extends Array<any>
? RecNullValuesToOptionalArray<T[number]>
: T extends object
? NullValuesToOptional<{ [K in keyof T]: RecNullValuesToOptional<T[K]> }>
: T;
interface RecNullValuesToOptionalArray<T>
extends Array<RecNullValuesToOptional<T>> {}
測試類型:
interface A {
a: string;
b: string | null;
}
interface C {
c: string;
d: A | null;
e: A[];
f: number[] | null;
}
/*
type EFormatted = {
c: string;
e: {
a: string;
b?: string | null | undefined;
}[];
d?: {
a: string;
b?: string | null | undefined;
} | null | undefined;
f?: number[] | null | undefined;
}
=> type EFormatted is the "flattened" version of
type E and used for illustration purposes here;
both types E and EFormatted are equivalent, see also Playground
*/
type E = RecNullValuesToOptional<C>
用一些數據測試:
const e: E = {
c: "foo",
d: { a: "bar", b: "baz" },
e: [{ a: "bar", b: "qux" }, { a: "quux" }]
};
const e2: E = {
c: "foo",
d: { a: "bar", b: "baz" },
e: [{ b: "qux" }, { a: "quux" }]
}; // error, a missing (jep, that's OK)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.