Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Partial<> on specific key

I have a typescript interface describing mongodb database data like :

interface Foo {
  _id: string,
  name: string,

  fish: {
    _id: string,
    name: string,   
  },
}

I have a method that is building one data to insert in the database, like :

function pushNewFish() {
   const obj: Foo = {
      name: 'obiwan',

      fish: {
         name: 'kenobi',
      },
  };

  // ...
}

The problem is : I do not implements every _id elements that are specific to database.

I have the possibility to use Partial<Foo> but it's not what I'm looking for.

I also have the possibility to turn every _id: string into _id ?: string, but it feels wrong.

Is there a way to do :

interface FooDatabase { ... }

type Foo = Partial<'_id', FooDatabase>;

? Thanks

like image 486
Orelsanpls Avatar asked Apr 15 '26 23:04

Orelsanpls


1 Answers

If only certain _id fields should be optional then define a new utility type, that only declares the selected keys as optional:

type Optional<T, K extends keyof T> = Partial<Pick<T, K>> & Omit<T, K>

interface FooDatabase {
  _id: number;
  foo: string;
  bar: string;
}

type Foo = Optional<FooDatabase, '_id'>

Playground Link


A recursive solution (for nested objects) where each key of the same singleton type is made optional:

type Primitive = number | string | boolean | undefined | null | any[];
type Optional<T, K extends keyof T> = { [P in K]?: T[P] } & { [P in Exclude<keyof T, K>]: T[P] extends Primitive ? T[P] : Optional<T[P], keyof T[P] & K> };

Playground Link

like image 176
iY1NQ Avatar answered Apr 17 '26 12:04

iY1NQ