1
type Foo = {
  nested:{
    unwanted:string
    wanted:string
  }
}

type Bar = {
  foos: Foo[]
}

I would like to exclude unwanted from Foo[] and get a type back with the new shape in an array.

type Excluded = Bar['foos'][number]['nested'] //the leaf type
type DoesntWork = Omit<Bar['foos'][number]['nested'],'unwanted'> //what i tried :(
pailhead
  • 5,162
  • 2
  • 25
  • 46
  • If I run your code in Typescript it kind of worked. https://www.typescriptlang.org/play?#code/C4TwDgpgBAYg9nKBeKBvAUFKA7CBnYCAEwC4MssBXbAdwENtDSCAnAS2wHNML7HiSrDtywBfdOPShIUAEJ0WyNDwBmCPCVgIA2gF0J6KeGgBRAB4BjADaUixJQHkAtm2AAeeS20ByNXDzeutrYlE4ARhAsQd64BMSBADTe1HxM3gB86EA – Torben Feb 17 '23 at 09:06

2 Answers2

1

Looking at this answer, a working solution could be:

interface Foo {
    nested: {
        wanted: string,
        unwanted: string
    }
}

interface Bar {
  foos: Array<Foo>
}

type Modify<T, R> = Omit<T, keyof R> & R;

type FoosWithoutUnwanted = Modify<Foo, {
    nested: {
        wanted: string
    }
}>

type Works = Modify<Bar, {
    foos: Array<FoosWithoutUnwanted>
}> 

Even if this works, I think that declaring different Interfaces would be a better approach:

interface Nested {
    wanted: string;
}

interface NestedWithUnwanted extends Nested {
    unwanted: string;
}

interface Foo {
    nested: Nested
}

interface FooWithUnwanted {
    nested: NestedWithUnwanted
}

interface Bar {
    foos: Array<Foo>;
}

interface BarWithUnwanted {
    foos: Array<FooWithUnwanted>;
}
0

This could work:

type Foo = {
  nested: {
    unwanted: string;
    wanted: string;
  };
};

type Bar = {
  foos: Foo[];
  untouched: number[];
};

type BarWithFoosArrayWithoutUnwanted = {
  [K in keyof Bar as Extract<K, "foos">]: {
    [KN in keyof Bar[K] as Extract<KN, "nested">]: Omit<
      Bar["foos"][number]["nested"],
      "unwanted"
    >;
  }[];
} & {
  [K2 in keyof Bar as Exclude<K2, "foos">]: Bar[K2];
};

const a: BarWithFoosArrayWithoutUnwanted = {
  foos: [{ nested: { wanted: "asdf" } }],
  untouched: [1, 2, 3],
};

There is a lot of hardcoded reference to the properties names though, so it might not be a very practical generic solution.

colinD
  • 1,641
  • 1
  • 20
  • 22