TypeScript'te birleştirme türüyle interface'i özyinelemeli olarak nasıl atlayabilirim?


Birleşim tiplerinde bulunan türleri özyinelemeli olarak çıkarmak ve bazı birleşim tiplerini kaldırmak istiyorum

İşte örnek.

Normal ve Admin birleşim türleri olmalıdır

interface Admin {
    admin: never;
}

interface Normal {
    normal: never;
}


interface A {
    a: number;
    b: Admin | number;
    c: Normal | string;
    d?: number | string | null;
    e: {
        f: Admin | string;
        g: number;
    };
    h: {
        i: {
            j: Admin | number;
            k: string;
        };
    };
    l: Normal | boolean;
}


type OmitNormal = OmitRecursiveByType<A, Admin>; 

Ve sonucu böyle istiyorum.

{
    a: number;
    c: string;
    d?: number | string | null;
    e: {
        g: number;
    };
    h: {
        i: {
            k: string;
        };
    };
    l: boolean;
}

Bu durumda, Admin birleşim tipine sahip anahtar kaldırılır. Ancak Normal olan anahtar kaldırılmaz.

İşte başka bir örnek

interface A {
    a: number;
    b: Admin | number;
    c: Normal | string;
    d: null|number
}

type OmitAll = OmitRecursiveByType<A, Admin|Normal>;

sonuç

{
   a: number;
   d: number|null;
}

İşte diğer örnek

interface A {
    a: number;
    b: string;
    c: number|string;
    d: number|null;
    e: {
       f: string;
       g: number|null;
    }
}
type NotStringA = OmitRecursiveByType<A, string>

sonuç

{
    a: number;
    d: number|null;
    e: {
       g: number|null;
    }
}

OmitRecursiveByType<T, P>'yi nasıl yapabilirim?

Cevap #1

Açıklamanız ve örnekleriniz temel alındığında, görünüşe göre aşağıdakilere ihtiyacınız var:

  • Bir özelliğin değer türü P ile çakışıyorsa, özellik kaldırılır.
  • Eğer bir özelliğin değeri bir nesne ise, yukarıdaki adım özyinelemeli olarak uygulanır.
  • Sonuçta, tüm Admin ve Normal örnekleri kaldırılır.

Eğer bu sizin probleminizi özetliyorsa, aşağıdaki tür ile çözülmelidir:

type OmitRecursiveByType<T extends Object, P> = {
    [K in keyof T]: T[K] extends object
    ? OmitRecursiveByType<T[K], P> 
    : Extract<T[K], P> extends never
      ? Exclude<T[K], Admin | Normal>
      : never
}