typescript deep keyof when field is an option

30 Views Asked by At

I create an function to select and keyof of deep object. but I don't know why this keyof on my object is not work when it is an option.


type Database = {
    User?: {
        id: string
        name: string
    },
    Post?: {   // if i remove ? it work but it should be an option
        id: string
        content: string
    }
}

type SelectQuery<T> = {
    [Table in keyof T]?: {
        select: {
            [field in keyof T[Table]]?: boolean
        }
    }
}


function select(query: SelectQuery<Database>) {}

select({
    Post: {
        select: {
          // it should suggest content and id here

        
        }
    }
})

Playground Link

1

There are 1 best solutions below

0
wonderflame On BEST ANSWER

The problem is that you have nested optional fields in your Database type and when you access one table you get a type tableFields | undefined and keyof returns never for this case. Example:

// never
type Case1 = keyof Database['Post']

To fix this issue you can use built-in NonNullable utility type:

// "id" | "content"
type Case2 = keyof NonNullable<Database['Post']>

Usage:

type SelectQuery<T> = {
  [Table in keyof T]?: {
    select: {
      [field in keyof NonNullable<T[Table]>]?: boolean;
    };
  };
};

playground