1

In the below (and attached) example, I am trying to pass nested type omissions using generics with the type DeepKeyOf<T>. On it's own, DeepKeyOf<T> works as expected, it's only when I try to pass around generics that extend DeepKeyOf<T> that it doesn't work.

Below, I have MyInterface<TEntity extends IBaseEntity, TOmissions extends DeepKeyOf<TEntity>>, which is trying to take in TOmissions and pass those to DeepOmittedEntity. As far as I can tell the types line up, what am I missing?

// https://medium.com/xgeeks/typescript-utility-keyof-nested-object-fa3e457ef2b2
type DeepKeyOf<T> = {
    [Key in keyof T & (string | number)]: T[Key] extends object ? `${Key}` | `${Key}.${DeepKeyOf<T[Key]>}` : `${Key}`
}[keyof T & (string | number)];

// DeepOmit works as expected - https://stackoverflow.com/a/75823617/3329760
type DeepOmit<T, K extends PropertyKey> = {
    [P in keyof T as P extends K ? never : P]: DeepOmit<T[P], K extends `${Exclude<P, symbol>}.${infer R}` ? R : never>
}

// Combining DeepKeyOf and DeepOmit works perfectly!
type DeepOmittedEntity<TEntity extends IBaseEntity, TOmissions extends DeepKeyOf<TEntity>> = DeepOmit<TEntity, "id" | TOmissions>;

interface IBaseEntity {
    id: string;
    more: string;
    other: string;
}

// This works as expected
const someObject: DeepOmittedEntity<IBaseEntity, "more"> = {
    other: "this works"
}

// The add method does not like TOmissions - see linked example
interface MyInterface<TEntity extends IBaseEntity, TOmissions extends DeepKeyOf<TEntity>> {
    add(entities: DeepOmittedEntity<TEntity, TOmissions>[]): void;
}

Playground

EDIT 1:

If I replace DeepKeyOf<T> with string, everything works, but the intellisense doesn't work for obvious reasons.

Agrejus
  • 722
  • 7
  • 18

0 Answers0